2020년 3월 12일 목요일

[CentOS8] Cockpit 사용하기 -브라우저에서 서버 관리


Cockpit은 리눅스 서버를 브라우저에서 모니터링 및 관리/제어 할 수 있도록 해주는 도구입니다.
CentOS 8 에서는 Cockpit이 기본 탑재되어 별도의 설치 없이 사용이 가능합니다.




설치하기





다음의 명령어로 자신의 CentOS 서버에 Cockpit이 설치되어있는지 확인할 수 있습니다.




sudo yum list installed | grep cockpit





Cockpit이 설치되어있을 경우 위처럼 확인할 수 있습니다.




설치되어있지 않다면 다음 명령어를 입력하여 설치합니다.




sudo yum install cockpit




서비스 시작 및 등록





Cockpit 서비스를 실행하기 위해 아래 명령어를 입력합니다.




sudo systemctl start cockpit




아래의 명령어로 Cockpit을 서비스에 등록할 수 있습니다.




sudo systemctl enable cockpit.socket




브라우저에서 접속하기





웹브라우저에서 Cockpit을 실행 중인 서버의 9090 포트로 접근하면 관리 페이지로 접근이 가능합니다.





root 계정과 비밀번호로 로그인이 가능합니다.




접속이 안되는 경우





접속이 불가능한 경우 9090 포트가 정상적으로 열려있거나 Cockpit 서비스가 방화벽 예외처리 되어있는지 확인해봅니다.




아래의 명령어로 열려있는 포트를 확인 합니다.




sudo firewall-cmd --list-posrts





9090포트가 열려있지 않습니다.




아래의 명령어로 방화벽 예외 처리된 서비스를 확인합니다.




sudo firewall-cmd --list-service





Cockpit이 방화벽 예외 서비스로 등록되어있습니다.




9090 포트 혹은 cockpit 서비스가 예외처리 되어있지 않은 경우 아래의 명령어로 방화벽 예외처리를 해줍니다.




sudo firewall-cmd --permanent --zone=public --add-service=cockpit
sudo firewall-cmd --permanent --zone=public --add-port=9090/tcp




위의 두 명령어 중 하나만 수행한 후 아래의 명령어로 방화벽 규칙을 새로 고침 해주면 됩니다.




sudo firewall-cmd --reload

[Spring] Jasypt를 이용하여 Property 암호화 하기 + 메이븐 플러그인


Spring 프로젝트의 Properties 파일에는 DB 연결정보, 이메일 계정, API Key 등의 보안에 민감한 정보들이 포함될 수 있습니다.
이 상태에서 프로젝트를 그대로 공유하게 되면 보안에 심각한 문제가 생길 수 있습니다.
이를 방지하기 위해 Spring 프로젝트에서 jasypt-spring-boot의 비밀번호 기반 암호화를 이용하여 중요한 정보들을 암호화하는 방법을 설명합니다.




참고
https://github.com/ulisesbocchio/jasypt-spring-boot




Dependency 추가





프로젝트의 pom.xml에 다음 Dependency를 추가합니다.




<dependency>
 <groupId>com.github.ulisesbocchio</groupId>
 <artifactId>jasypt-spring-boot-starter</artifactId>
 <version>3.0.2</version>
</dependency>




Property 설정





적용 및 테스트를 위해 application.properties에 다음과 같이 비밀번호를 작성합니다.
(실사용 시에는 비밀번호를 프로퍼티에서 삭제해주세요)




jasypt.encryptor.password=ExamplePassword123




-주의-
위처럼 비밀번호를 프로퍼티에 작성할 경우 결과적으로 비밀번호가 노출되기 때문에 보안 효과가 없습니다.
테스트 외에 실제 서비스에서 사용한다면 꼭 프로퍼티 파일 내 비밀번호를 삭제하고
비밀번호를 시스템 변수나 환경 변수에 등록하여 사용하시기를 권장합니다.




필수 프로퍼티는 jasypt.encryptor.password 밖에 없으며
이 외에 추가할 수 있는 프로퍼티는 다음과 같습니다.
작성하지 않으면 아래의 기본값이 적용됩니다.
자세한 내용은 https://github.com/ulisesbocchio/jasypt-spring-boot에서 확인해주세요.




jasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256
jasypt.encryptor.key-obtention-iterations=1000
jasypt.encryptor.pool-size=1
jasypt.encryptor.provider-name=SunJCE
jasypt.encryptor.provider-class-name=null
jasypt.encryptor.salt-generator-classname=org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.RandomIvGenerator
jasypt.encryptor.string-output-type=base64
jasypt.encryptor.proxy-property-sources=false
jasypt.encryptor.skip-property-sources=empty list




사용하기





테스트 작성





테스트 유닛을 작성하여 암복호화가 작동하는지 확인해봅니다.




@SpringBootTest
public class JasyptTests {

 @Autowired
 StringEncryptor configurationEncryptor;
 
 static final String TEST_PASSWORD = "테스트용 비밀번호 입니다.";
 
 @Test
 public void encryptTest() {
  String encryptedPassword = configurationEncryptor.encrypt(TEST_PASSWORD);
  System.out.println("encrypted password is : " + encryptedPassword);
  String decryptedPassword = configurationEncryptor.decrypt(encryptedPassword);
  assertThat(decryptedPassword).isEqualTo(TEST_PASSWORD);
 }
}




테스트가 성공하면 콘솔에서 아래와 비슷한 암호화된 문자열을 확인할 수 있습니다.




encrypted password is : cA8DhDVl27MeHDSQRn8GSfUFGn+Qif2n9Zv8OLlq67yiijVJTe0wqwzRE9eIBSlfNQ5HeYirCXMZFwXPbO7LAHe+q/PeWxNcYE9Tr1LeBEs=




프로퍼티에 적용





공개되면 안 되는 프로퍼티 값을 암호화한 후 아래와같이 ENC()로 감싸서 작성하게 되면 프로퍼티를 불러올 때 자동으로 복호화하여 적용합니다.




test=ENC(cA8DhDVl27MeHDSQRn8GSfUFGn+Qif2n9Zv8OLlq67yiijVJTe0wqwzRE9eIBSlfNQ5HeYirCXMZFwXPbO7LAHe+q/PeWxNcYE9Tr1LeBEs=)




여기까지 적용하게 되면 프로퍼티 파일 노출로 인한 정보 노출을 방지할 수 있습니다.




프로퍼티를 불러올 때 정상적으로 복호화가 되는지 테스트를 위해
위의 JasyptTests 클래스에 다음과 같이 테스트코드를 추가하였습니다.




@SpringBootTest
public class JasyptTests {
 // 기존 코드 생략
 ...

 @Value("${test}")
 String test;

 @Test
 public void propertyTest() {
  System.out.println("test password is : " + test);
  assertThat(test).isEqualTo(TEST_PASSWORD);
 }
}




테스트 정상적으로 완료되었다면 콘솔에서 복호화된 문자열을 확인할 수 있습니다.




test password is : 테스트용 비밀번호 입니다.




플러그인





위의 방식으로 민감한 정보들은 전부 암호화하여 사용하는 걸로도 충분하지만
플러그인과 메이븐 명령어를 이용하여 간단하게 암호화하는 방법을 소개합니다.




이를 위해서는 메이븐 명령어를 사용 가능해야 하며 메이븐 명령어의 기본적인 사용 방법은 다른 가이드를 참고해 주시길 바랍니다.




플러그인 추가





우선 플러그인 사용을 위해 pom.xml에 플러그인을 추가합니다.




<plugin>
 <groupId>com.github.ulisesbocchio</groupId>
 <artifactId>jasypt-maven-plugin</artifactId>
 <version>3.0.2</version>
</plugin>




프로퍼티 작성





프로퍼티를 작성할 때 암호화되지 않은 정보들을 DEC()로 감싸서 작성하게 되면 플러그인을 이용하여 일괄적으로 암호화 할 수 있습니다.




test=DEC(암호화되지 않은 테스트 프로퍼티 입니다.)




명령어를 이용하여 암복호화





콘솔에서 아래의 명령어로 application.properties 파일 내 DEC()로 감싸진 정보들을 일괄적으로 암호화 할 수 있습니다.
환경변수에 jasypt.encryptor.password를 등록해 놨다면 아래의 명령어에서 생략 가능합니다.




mvn jasypt:encrypt -Djasypt.encryptor.password="ExamplePassword123"




역으로 복호화도 가능합니다.




mvn jasypt:decrypt -Djasypt.encryptor.password="ExamplePassword123"




이를 이용하면 암호화된 정보를 좀 더 쉽게 수정하고 다시 암호화가 가능합니다.




프로퍼티 파일 지정하기





위처럼 명령어를 이용하면 application.properties가 아닌 application-test.properties 같은 파일은 암복호화가 되지 않습니다.
다른 파일을 암복호화 하고 싶을 경우 jasypt.plugin.path 파라미터로 파일을 지정할 수 있습니다.




mvn encrypt:encrypt -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.path="file:src/main/test/application-dev.properties"




단독 값 암복호화 하기





아래의 명령어로 프로퍼티 파일과 별개로 단독 문자열을 암호화하거나 복호화가 가능합니다.




mvn jasypt:encrypt-value -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.value="theValueYouWantToEncrypt"

mvn jasypt:decrypt-value -Djasypt.encryptor.password="ExamplePassword123" -Djasypt.plugin.value="DbG1GppXOsFa2G69PnmADvQFI3esceEhJYbaEIKCcEO5C85JEqGAhfcjFMGnoRFf"





[Spring Security] PasswordEncoder를 Bean에 등록하여 사용하기 -PasswordEncoderFactories로 DelegatingPasswordEncoder 생성하기


현재 진행 중인 프로젝트에서 비밀번호 관리를 위해 Password Encoder를 사용하고 있습니다.
Password Encoder 구현체를 Bean에 등록하여 사용하기 위해 직접 DelegatingPasswordEncoder를 생성하여 Bean에 등록하였는데
Speing Security 5.0 이후부터는 DelegatingPasswordEncoder를 생성해주는 Factory 클래스가 추가되어 직접 생성할 필요가 없어졌기 때문에 해당 문서를 작성하였습니다.




Spring Security가 프로젝트에 적용되어있다면 다음과 같이 @Bean을 작성하기만 하면 됩니다.




@Configuration
public class SecurityConfiguration {

 @Bean
 public PasswordEncoder passwordEncoder() {
  return PasswordEncoderFactories.createDelegatingPasswordEncoder();
 }
}




사용할 때는 다음과 같이 사용할 수 있습니다.




class PasswordTests extends ApplicationTests {

 @Autowired
 PasswordService passwordTest;
 
 @Test
 void test() {
  String rawPassword = "비밀번호 입니다.";
  String encrypted = passwordTest.encrypt(rawPassword);

  assertThat(encrypted).contains("bcrypt");
  assertThat(passwordTest.match(rawPassword, encrypted)).isTrue();
 }

}