mv .idea /tmp/.idea_old

git rm -r .idea 

git commit -m "Remove .idea"

mv /tmp/.idea_old .idea


mv .gradle /tmp/.gradle_old

git rm -r .gradle 

git commit -m "Remove .gradle"

mv /tmp/.gradle_old .gradle




자주 사용하는 명령어 모음


  • 비주얼 스튜디오 코드(VS Code) 권한 문제 에러
    • 관련 로그: Could not create temporary directory
    • 해결방법: 

      sudo chown -R kjlee:staff ~/Library/Caches/



교회 홈페이지에 SSL 인증서 적용하려다가 하루종일 삽질한 이야기.

 

0. 참고 블로그

 

1. 적용(삽질) 히스토리

1.1 삽질 이유

  • 아마존 Lightsail을 이용해서 Wordpress를 설치하면, Bitnami 패키지를 사용하여 설치가 된다.
    • 설치 위치: /opt/bitnami/apache
    • Bitnami Wordpress : 유명한 무료 APM 툴 중 하나
      • https://bitnami.com/stack/wordpress
      • APM : Apache + PHP + MySQL
  • 아마존 Lightsail에 이미 또다른 Apache2가 설치되어 있었다.
    • 설치 위치: /etc/apache2
  • certbot 공식 메뉴얼을 사용하면 /etc/apache2 설정을 참고하여 SSL 인증서 발급을 시도한다.
    • /etc/apache2 설정에서는 현재 설정된 웹서비스가 없으므로 정상적으로 처리되지 않는다.
    • 에러 발생 --> No names were found in your configuration files. Please enter in your domain
  • 결론은 bitnami wordpress 에 SSL 인증서를 발급받기 위해서는 bitnami 공식 문서를 참고해야 했고, 나는 이것을 이번에 처음 알았다. (공식문서가 있다는 것도...)

 

1.2 삽질 히스토리 

  • certbot 공식 메뉴얼 적용 --> 실패
    • 인터넷에서 한글로 검색하면 대부분 certbot 또는 certbot-auto 에 대해서만 나옴.
    • certbot-auto 의 최신버전이 certbot
      • certbot-auto는 구버전이고, 설정이 복잡함.
    • 2019년 2월 보안 이슈 발생 : TLS-SNI-01 취약점 발견됨
      • 2019년 2월 13일부터 certbot 에서는 더이상 TLS-SNI-01 지원하지 않는다고 함.
      • --> 최신버전의 certbot 사용 필수!
  • bitnami wordpress 공식 메뉴얼 적용 --> 성공
    • lego 사용함.
    • lego --tls 옵션 시 TLS-ALPN-01 사용함.
    • bitnami 커뮤니터에서는 최신 lego(2.1.0) 사용하면 괜찮다는 의견이 있으나  2019년 2월 13일 이후에 다시 확인이 필요함.

 

2. Bitnami 용 Apache 전용 메뉴얼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 1단계:레고 클라이언트 설치
cd /tmp
curl -s https://api.github.com/repos/xenolf/lego/releases/latest | grep browser_download_url | grep linux_amd64 | cut -'"' -4 | wget --
tar xf lego_vX.Y.Z_linux_amd64.tar.gz
sudo mv lego /usr/local/bin/lego
 
# 2단계:도메인에 대한 권한 부여 인증서 생성
# - Turn off all Bitnami services:
sudo /opt/bitnami/ctlscript.sh stop
 
sudo lego --tls --email="MyID@gmail.com" --domains="도메인명" --domains="www.도메인명" --path="/etc/lego" run
 
# - Now it be generated in the /etc/lego/certificates directory.
 
# 3단계:웹 서버가 인증서를 사용하도록 구성
# - 사용 중인 웹 서버에 따라 새 SSL인증서 및 인증서 키 파일을 올바른 위치에 연결합니다. 
# - 파일 권한을 업데이트하여 루트 사용자만 읽을 수 있도록 합니다. 
 
## Apache의 경우:
sudo mv /opt/bitnami/apache2/conf/server.crt /opt/bitnami/apache2/conf/server.crt.old
sudo mv /opt/bitnami/apache2/conf/server.key /opt/bitnami/apache2/conf/server.key.old
sudo mv /opt/bitnami/apache2/conf/server.csr /opt/bitnami/apache2/conf/server.csr.old
sudo ln -/etc/lego/certificates/도메인명.key /opt/bitnami/apache2/conf/server.key
sudo ln -/etc/lego/certificates/도메인명.crt /opt/bitnami/apache2/conf/server.crt
sudo chown root:root /opt/bitnami/apache2/conf/server*
sudo chmod 600 /opt/bitnami/apache2/conf/server*
 
## NGINX의 경우:
sudo mv /opt/bitnami/nginx/conf/server.crt /opt/bitnami/nginx/conf/server.crt.old
sudo mv /opt/bitnami/nginx/conf/server.key /opt/bitnami/nginx/conf/server.key.old
sudo mv /opt/bitnami/nginx/conf/server.csr /opt/bitnami/nginx/conf/server.csr.old
sudo ln -/etc/lego/certificates/DOMAIN.key /opt/bitnami/nginx/conf/server.key
sudo ln -/etc/lego/certificates/DOMAIN.crt /opt/bitnami/nginx/conf/server.crt
sudo chown root:root /opt/bitnami/nginx/conf/server*
sudo chmod 600 /opt/bitnami/nginx/conf/server*
 
## 모든 Bitnami서비스를 다시 시작
sudo /opt/bitnami/ctlscript.sh start 
 
# 4단계:구성 테스트
# - you can test it by browsing to https://도메인명 
# -> Bitnami응용 프로그램의 보안 시작 페이지가 표시됩니다. 브라우저 주소 표시줄에서 자물쇠 아이콘을 클릭하면 도메인 및 SSL인증서의 세부 정보가 표시됩니다.
 
# 5단계:인증서 갱신
# - 인증서는 90일 동안만 유효
# - 인증서가 만료되기 전에 자동으로 갱신하려면 위의 작업을 수행하는 스크립트를 작성하고 스크립트를 주기적으로 실행하도록 cron작업을 예약하십시오.
 
sudo vi /etc/lego/renew-certificate.sh
# --------------
#!/bin/bash
 
sudo /opt/bitnami/ctlscript.sh stop apache
sudo /usr/local/bin/lego --tls --email="MyID@gmail.com" --domains="도메인명" --domains="www.도메인명" --path="/etc/lego" renew
sudo /opt/bitnami/ctlscript.sh start apache
# --------------
 
sudo chmod +/etc/lego/renew-certificate.sh
 
sudo crontab -e
# ---------------
0 0 1 * * /etc/lego/renew-certificate.sh 2> /dev/null
# ---------------
 
# HTTPS redirect
vi /opt/bitnami/apps/wordpress/conf/httpd-prefix.conf
# ---------------
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R=301,L]
# ---------------
 
vi /opt/bitnami/apps/wordpress/htdocs/wp-config.php
# ---------------
# original 
# define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
# define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
# http to https
define('WP_SITEURL''https://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME''https://' . $_SERVER['HTTP_HOST'] . '/');
# ---------------
# apache server restart
sudo /opt/bitnami/ctlscript.sh restart apache
cs
 

 

3. Let's Encrypt (certbot) 공식 메뉴얼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 패키지 설치
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot python-certbot-apache 
 
# SSL 인증서 발급
## - 1.1 인증서를 발급 받고 자동으로 Apache 설정 파일까지 수정.
$ sudo certbot --apache
 
## - 1.2 인증서를 발급 받은 뒤에 직접 설정하는 방법
# sudo certbot --apache certonly
 
## - 2.1 이메일 주소를 묻는 메세지 -> 올바른 메일 주소를 입력
## - 2.2 동의하는지 묻는 메세지 ->  A를 입력
## - 2.3 이메일 주소를 공유하고자 하는지 묻는 내용 -> N
## - 2.4 생성하고자 하시는 도메인을 선택하는 부분 
## -   -> 도메인에 해당되는 숫자 번호를 입력. 
## -      만약 전체 도메인에 적용하고자 하시는 경우 빈칸으로 남겨주시고, 
## -      원하시는 도메인을 콤마(,) 또는 스페이스로 분리하여 입력해 주시면 됩니다.
## -      입력한 도메인: 도메인명 www.도메인명
## - 2.5 위의 정보가 모두 입력되면 자동으로 SSL 인증서가 생성되게 됩니다.
 
# renewal test
$ sudo certbot renew --dry-run
 
# 자동 갱신 (root 계정)
# ---------------
0 0 1 * * /bin/bash --'certbot renew --quiet'
# ---------------
 
# 갱신후 바로 적용을 위해서 아파치를 다시 시작해 주시는것이 좋습니다.
# ---------------
0 2 * * * sudo certbot-auto -q renew && /etc/init.d/apache2 restart
# ---------------
cs

 

 

4. 기본 지식

4.1 인증서 등록 기관

  • Let's Encrypt - TLS 인증서를 무료로 발급해 주는 비영리기관.
  • 발급된 인증서는 유효기간이 90일이며, 만료 30일 전부터 갱신할 수 있다. 갱신 가능 횟수는 무제한.
  • 등록 관련 매뉴얼: https://certbot.eff.org/lets-encrypt/ubuntuxenial-apache
 

4.2 인증서 발급 방식 : 추천 인증서 발급 프로그램은 certbot 

  1. standalone
    • standalone 명령어를 사용하면 certbot에 내장된 웹 서버를 이용해서 도메인만으로 인증서가 발급 되고, 갱신 절차도 자동으로 처리된다. 
    • *.example.com 형태의 와일드카드 서브 도메인 인증서는 발급할 수 없다.
  2. webroot
    • webroot 명령어를 사용하면 자신의 웹 서버에서 작동중인 웹사이트를 이용해서 인증서를 발급하고, 갱신 절차도 자동으로 처리된다. 
    • *.example.com 형태의 와일드카드 서브 도메인 인증서는 발급할 수 없다.
  3. dns
    • 도메인이 연결된 DNS에 TXT 레코드를 생성해서 인증서를 발급하는 방식으로, 인증서 발급 과정에 웹 서버가 필요 없고 *.example.com 형태의 와일드카드 서브 도메인 인증서를 발급할 수 있다. 
    • 다만 매번 인증서를 갱신할 때마다 DNS에 TXT 레코드를 새로 생성해야 하므로, 외부에서 TXT 레코드를 입력할 수 있도록 DNS가 API를 제공하는 경우에만 갱신 과정을 자동으로 처리할 수 있다.

4.3 가장 간단한 방식

  • - 서트봇 홈페이지로 들어가서 자신의 서버 사양을 선택하면 설명 화면이 나온다.
  • - 문서를 읽으면서 터미널에 명령어를 친다.
  • - 몇몇 정보를 입력하면 알아서 설정해주고, 3개월 마다 갱신도 자동으로 해준다.
  • - 참 쉽죠?

4.4 SSL 인증서 파일 

  • certbot 으로 발급한 인증서
    • 파일 위치 : /etc/letsencrypt/live/
    • 발급된 파일
      • privkey.pem : 인증서를 위한 비밀키 파일입니다.
      • fullchain.pem : 인증서와 체인 인증서가 합쳐진 전체 파일입니다. 대부분의 서버 소프트웨어에서 사용됩니다.
      • chain.pem : Nginx >=1.3.7에서 OCSP stapling을 위해서 사용됩니다.
      • cert.pem : 생성된 인증서 파일입니다.
  • lego 로 발급한 인증서 
      • 파일 위치 : /etc/lego/certificates/
      • 발급된 파일
        • 도메인명.key
        • 도메인명.crt

 

5. 테스트 

테스트 결과 : 
 

 

6. 3개월마다 갱신 (수동 처리 필요)

- crontab이 제대로 동작하지 않아 수동으로 명령어 실행해야 했다.
sudo /etc/lego/renew-certificate.sh​

'IT > Server' 카테고리의 다른 글

[LigthtSail] 인스턴스 업스레이드 방법  (0) 2018.11.06
[LightSail] 개발 팁  (0) 2018.11.06

시퀀스 자리수 맞추기

   SQL> select 시퀀스명.nextval from dual;                        --> '1'

   SQL> select LPAD(시퀀스명.nextval, 5, 0) from dual;    --> '00001'


'IT > Database' 카테고리의 다른 글

[Oracle] 시퀀스 수정  (0) 2019.01.28

시퀀스 수정하는 방법 


1. 차이값만큼 증분값을 설정 
   SQL> alter sequence [시퀀스명] increment by [증분값];


2. 확인 및 시퀀스 1 증가.

   SQL> select 시퀀스명.nextval from dual

 

3. 증분값을 다시 원래의 증가값으로 설정
   SQL> alter sequence 시퀀스명 increment by 1 [또는 원하는 시퀀스 시작값];



시퀀스 사용법

1. 현재값 확인

   SQL> select 시퀀스명.currval from dual


2. 시퀀스 1 증가 

   SQL> select 시퀀스명.nextval from dual


'IT > Database' 카테고리의 다른 글

시퀀스 자리수 맞추기  (0) 2019.01.28

참고 블로그 - https://extrememanual.net/27713


1. 스냅샷 생성.

2. 생성한 스냅샷에서 새로운 인스턴스 생성

3. 신규 인스턴스에서 "인스턴스 계획" 을 선택

4. 신규 인스턴스 생성.

5. 구 인스턴스에서 고정 IP 분리

6. 고정 IP를 신규 인스턴스와 연결.

7. 구 인스턴스에 있는 스냅샷 삭제.

8. 구 인스턴스 중지 및 삭제.


'IT > Server' 카테고리의 다른 글

AWS Lightsail Apache 서버에 SSL 인증서 등록 삽질의 흔적  (0) 2019.02.08
[LightSail] 개발 팁  (0) 2018.11.06


WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 


ssh 접속시 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!가 발생할 때가 있다.



원인
- RSA 키가 맞지 않아서 발생하는 문제.
- 이전에 해당 IP로 접속했을 때 정보가 저장되어 있다.


해결방법 : 해당 key 를 초기화 한다.

1. ssh-keygen -R '접속할 주소'

2. ssh '접속할 주소'


1) 문제

  • https://www.acmicpc.net/problem/1991
  • 이진 트리를 입력받아 전위 순회(preorder traversal), 중위 순회(inorder traversal), 후위 순회(postorder traversal)한 결과를 출력하는 프로그램을 작성하시오.

2) 풀이

 -  inorder, preorder, postorder 구현.


3) 코딩

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class BOJ_1991_트리_순회 {
static final int MAX_NODE_NUMBER = 26;

static class Node {
int left, right;
Node(int left, int right) {
this.left = left;
this.right = right;
}
}

public static void main(String[] args) throws IOException {
Node[] nodes = new Node[MAX_NODE_NUMBER + 1];
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine());
while (n-- > 0) {
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
int x = st.nextToken().charAt(0) - 'A';
char y = st.nextToken().charAt(0);
char z = st.nextToken().charAt(0);
int left = -1;
int right = -1;
if (y != '.') left = y - 'A';
if (z != '.') right = z - 'A';

nodes[x] = new Node(left, right);
}

preorder(nodes, 0);
System.out.println();

inorder(nodes, 0);
System.out.println();

postorder(nodes, 0);
System.out.println();

}

private static void postorder(Node[] nodes, int x) {
if (x == -1) return;
postorder(nodes, nodes[x].left);
postorder(nodes, nodes[x].right);
System.out.print((char)(x + 'A'));
}

private static void inorder(Node[] nodes, int x) {
if (x == -1) return;
inorder(nodes, nodes[x].left);
System.out.print((char)(x + 'A'));
inorder(nodes, nodes[x].right);
}

private static void preorder(Node[] nodes, int x) {
if (x == -1) return;
System.out.print((char)(x + 'A'));
preorder(nodes, nodes[x].left);
preorder(nodes, nodes[x].right);
}
}


https://www.acmicpc.net/problem/10844


문제

45656이란 수를 보자.

이 수는 인접한 모든 자리수의 차이가 1이 난다. 이런 수를 계단 수라고 한다.

N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. 

(0으로 시작하는 수는 없다.).



풀이

 1) 문제를 한글로 풀어본다.


 D(N) = 길이가 N인 계단 수의 개수 



 2) 점화식을 만든다.


 D[N][L] = D[N-1][L-1] + D[N-1][L+1]

    • L =    0 :  D[N][L] = D[N - 1][L + 1]

    • L = (1 ~ 8) : D[N][L] = D[N - 1][L - 1] + D[N - 1][L + 1]

    • L =    9 : D[N][L] = D[N - 1][L - 1]



 3) 코딩

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* 쉬운 계단 수
* https://www.acmicpc.net/problem/10844
*
* 문제
* 45656이란 수를 보자.
* 이 수는 인접한 모든 자리수의 차이가 1이 난다. 이런 수를 계단 수라고 한다.
* 세준이는 수의 길이가 N인 계단 수가 몇 개 있는지 궁금해졌다.
* N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구하는 프로그램을 작성하시오. (0으로 시작하는 수는 없다.)
*
* 입력
* 첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.
*
* 출력
* 첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
*
* 예제 입력 1
* 1
* 예제 출력 1
* 9
* 예제 입력 2
* 2
* 예제 출력 2
* 17
*/
public class BOJ_10844_쉬운계단수 {
static final long MOD = 1000000000;

public static void main(String[] args) throws IOException {

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine());

long[][] d = new long[n+1][10];

for (int i = 1; i <= 9; i++) {
d[1][i] = 1;
}

for (int i = 2; i <= n; i++) {
for (int j = 0; j <= 9; j++) {
d[i][j] = 0;
if (j - 1 >= 0) d[i][j] += d[i-1][j-1];
if (j + 1 <= 9) d[i][j] += d[i-1][j+1];
d[i][j] %= MOD;
}
}

long result = 0;
for (int i = 0; i <= 9; i++) {
result += d[n][i];
}

result %= MOD;

System.out.println(result);
}
}


'ALGORITHM > DP' 카테고리의 다른 글

11052번 - 붕어빵 판매하기  (0) 2018.07.21
11727번 - 2×n 타일링 2  (0) 2018.07.21
11726번 - 2×n 타일링  (0) 2018.07.21
1463 - 1로 만들기 성공  (0) 2018.07.20

https://www.acmicpc.net/problem/11052


문제

강남역에서 붕어빵 장사를 하고 있는 해빈이는 지금 붕어빵이 N개 남았다.

붕어빵 i개로 이루어진 세트 메뉴의 가격은 Pi 원이다.

세트 메뉴의 가격이 주어졌을 때, 해빈이가 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.



풀이

 1) 문제를 한글로 풀어본다.


 D(N) = N개의 붕어빵 팔아 얻은 최대 수익



 2) 점화식을 만든다.


 D(N) = Max(D[N], D[N-i] + P[i])



 3) 코딩

/**
* 붕어빵 판매하기

*
* 문제
* 강남역에서 붕어빵 장사를 하고 있는 해빈이는 지금 붕어빵이 N개 남았다.
*
* 해빈이는 적절히 붕어빵 세트 메뉴를 구성해서 붕어빵을 팔아서 얻을 수 있는 수익을 최대로 만드려고 한다. 붕어빵 세트 메뉴는 붕어빵을 묶어서 파는 것을 의미하고, 세트 메뉴의 가격은 이미 정해져 있다.
*
* 붕어빵 i개로 이루어진 세트 메뉴의 가격은 Pi 원이다.
*
* 붕어빵이 4개 남아 있고, 1개 팔 때의 가격이 1, 2개는 5, 3개는 6, 4개는 7인 경우에 해빈이가 얻을 수 있는 최대 수익은 10원이다. 2개, 2개로 붕어빵을 팔면 되기 때문이다.
*
* 1개 팔 때의 가격이 5, 2개는 2, 3개는 8, 4개는 10 인 경우에는 20이 된다. 1개, 1개, 1개, 1개로 붕어빵을 팔면 되기 때문이다.
*
* 마지막으로, 1개 팔 때의 가격이 3, 2개는 5, 3개는 15, 4개는 16인 경우에는 정답은 18이다. 붕어빵을 3개, 1개로 팔면 되기 때문이다.
*
* 세트 메뉴의 가격이 주어졌을 때, 해빈이가 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.
*
* 입력
* 첫째 줄에 해빈이가 가지고 있는 붕어빵의 개수 N이 주어진다. (1 ≤ N ≤ 1,000)
*
* 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)
*
* 출력
* 해빈이가 얻을 수 있는 최대 수익을 출력한다.
*
* 예제 입력 1
* 4
* 1 5 6 7
* 예제 출력 1
* 10
* 예제 입력 2
* 5
* 10 9 8 7 6
* 예제 출력 2
* 50
* 예제 입력 3
* 10
* 1 1 2 3 5 8 13 21 34 55
* 예제 출력 3
* 55
* 예제 입력 4
* 10
* 5 10 11 12 13 30 35 40 45 47
* 예제 출력 4
* 50
* 예제 입력 5
* 4
* 5 2 8 10
* 예제 출력 5
* 20
* 예제 입력 6
* 4
* 3 5 15 16
* 예제 출력 6
* 18
*/

import java.io.*;
import java.util.*;

public class BOJ_11052_붕어빵 {

public static void main(String[] args) throws IOException {


int result = go();


System.out.println(result);

}

private static int go() throws IOException {
// 붕어빵 개수 입력 받음.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine());

int[] p = new int[n+1];

StringTokenizer st = new StringTokenizer(in.readLine(), " ");

// 세트 메뉴 가격 입력 받음.
for (int i = 1; i <= n; i++) {
p[i] = Integer.parseInt(st.nextToken());
}

int[] d = new int[n+1];

d[1] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
d[i] = Math.max(d[i], d[i-j] + p[j]);
}
}

return d[n];
}
}


'ALGORITHM > DP' 카테고리의 다른 글

10844번 - 쉬운 계단 수  (0) 2018.07.23
11727번 - 2×n 타일링 2  (0) 2018.07.21
11726번 - 2×n 타일링  (0) 2018.07.21
1463 - 1로 만들기 성공  (0) 2018.07.20

+ Recent posts