Outsider's Dev Story: Ubuntu 카테고리 글 목록https://blog.outsider.ne.kr/Stay Hungry. Stay Foolish. Don't Be Satisfied.2024-03-15T09:32:38+09:00Textcube 1.10.7 : Tempo primoLets' Encrypt 인증서 갱신하기Outsiderhttps://blog.outsider.ne.kr/11982016-02-26T02:48:05+09:002016-02-26T02:48:05+09:00<p>3달 정도 전에 <a href="https://blog.outsider.ne.kr/1178">Lets' Encrypt로 무료로 HTTPS 지원하기</a>에 대해서 공유했고 이 블로그에도 <a href="https://letsencrypt.org/">Let's Encrypt</a>의 인증서를 적용해서 사용하고 있다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/7478276665.gif" width="485" height="403" alt="만료기간이 임박한 인증서" title="" /></p>
<p>Let's Encrypt 인증서는 유효기간이 90일이기 때문에 90일마다 갱신을 해주어야 한다. 작년 12월에 처음 적용해서 유효기간이 얼마 남지 않은 상황이라서 처음 인증서 갱신을 시도해 보았다. <a href="https://letsencrypt.readthedocs.org/en/latest/using.html#renewal">문서</a>에는 <code>crontab</code>을 이용하라고 되어 있지만 처음 해보는 갱신이므로 수동으로 직접 진행을 했다.</p>
<p><a href="https://blog.outsider.ne.kr/1178">이전 글</a>에 쓴 대로 <a href="https://github.com/letsencrypt/letsencrypt">letsencrypt 저장소</a>를 클론 받아서 서버에서 사용하고 있었으므로 확인차 폴더 내의 <code>letsencrypt-auto</code> 명령어를 실행하니 관련 의존성을 업데이트한다. 혹시나 해서 소스도 업데이트했는데 업데이트하지 않아도 상관없는 것 같다.</p>
<pre class="line-numbers"><code class="language-bash">$ ./letsencrypt-auto --help
Updating letsencrypt and virtual environment dependencies...You are using pip version 7.1.2, however version 8.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
....
Running with virtualenv: sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --help
letsencrypt-auto [SUBCOMMAND] [options] [-d domain] [-d domain] ...
</code></pre>
<p>저번에는 처음 사용해봐서 놓쳤지만, 실행파일이 <code>sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --help</code>에 설치가 되므로 이 명령어를 그냥 사용하면 된다.</p>
<pre class="line-numbers"><code class="language-bash">$ sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt renew
Checking for new version...
Requesting root privileges to run letsencrypt...
sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade renew
Processing /etc/letsencrypt/renewal/blog.outsider.ne.kr.conf
2016-02-25 16:49:57,329:WARNING:letsencrypt.cli:Attempting to renew cert from /etc/letsencrypt/renewal/blog.outsider.ne.kr.conf produced an unexpected error: Missing command line flag or config entry for this setting:
NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running letsencrypt in manual mode on a machine that is not your server, please ensure you're okay with that.
Are you OK with your IP being logged?
(You can set this with the --manual-public-ip-logging-ok flag). Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem (failure)
</code></pre>
<p>처음 실행을 했더니 IP를 공개적으로 로깅해도 되는지를 물어보면서 실패를 한다. 이는 아마도 이전에 인증서 발급을 <code>--manual</code>로 했기 때문으로 보인다. 오류 메시지에 나온 대로 <code>--manual-public-ip-logging-ok</code> 옵션을 추가해서 재시도했다.</p>
<pre class="line-numbers"><code class="language-bash">$ sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt renew --manual-public-ip-logging-ok
Checking for new version...
Requesting root privileges to run letsencrypt...
sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade renew --manual-public-ip-logging-ok
Processing /etc/letsencrypt/renewal/blog.outsider.ne.kr.conf
Make sure your web server displays the following content at
http://blog.outsider.ne.kr/.well-known/acme-challenge/vTubqqkFcCooMGnXXXXXXXX before continuing:
vTubqqkFcCooMGnFyZJzFK65uwJn9SXXXXXXXXXXXXXXXX
If you don't have HTTP server configured, you can run the following
command on the target server (as root):
mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" vTubqqkFcCooMGnFyZJzFK65uwJn9SXXXXXXXXXXXXXXXX > .well-known/acme-challenge/vTubqqkFcCooMGnXXXXXXXX
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"
Press ENTER to continue
new certificate deployed without reload, fullchain is /etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem (success)
</code></pre>
<p>처음 인증서를 발급받을 때와 같이 서버의 소유 여부를 확인할 수 있게 웹서버에서 인증키를 등록하게 나온다. <a href="https://blog.outsider.ne.kr/1178">이전 글</a>에서 했던 대로 웹서버에 등록한 뒤 엔터를 누르면 정상적으로 인증서가 업데이트되었다고 나온다.</p>
<p>인증서가 위치하는 <code>/etc/letsencrypt/archive/blog.outsider.ne.kr</code>에 가면 기존에는 새로운 인증서 파일(2가 붙은 파일)이 생기고 <code>/etc/letsencrypt/live/blog.outsider.ne.kr/</code>에 있는 심볼릭 링크도 새로운 파일로 업데이트된 것을 볼 수 있다.</p>
<pre class="line-numbers"><code class="language-bash">cert1.pem
cert2.pem
chain1.pem
chain2.pem
fullchain1.pem
fullchain2.pem
privkey1.pem
privkey2.pem
</code></pre>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/6067199762.gif" width="485" height="277" alt="갱신한 인증서" title="" /></p>
<p>nginx 서버를 리로드하고 브라우저에서 확인하면 위처럼 인증서의 유효기간이 갱신된 것을 볼 수 있다.</p>
<p>문서에 정확한 기간이 나와 있지 않지만, 인증서 갱신은 실제 만료기간이 다가왔을 때만 정상적으로 동작한다. 그래서 아래처럼 재시도하더라도 이미 인증서가 갱신되었으므로 새로 인증서를 갱신하지 않는다.</p>
<pre class="line-numbers"><code class="language-bash">$ sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt renew --manual-public-ip-logging-ok
Checking for new version...
Requesting root privileges to run letsencrypt...
sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --no-self-upgrade renew
Processing /etc/letsencrypt/renewal/blog.outsider.ne.kr.conf
The following certs are not due for renewal yet:
/etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem (skipped)
No renewals were attempted.
</code></pre>
<p><code>crontab</code>으로 자동갱신되도록 할 생각이었는데 manual로 인증서를 받아서인지 중간에 수동처리해야 하는 부분이 있어서 바로 <code>crontab</code>적용이 어려워 보인다. 이 부분은 나중에 시간이 나면 다시 확인해 봐야겠다.</p>
<p><strong><a href="https://blog.outsider.ne.kr/1198?commentInput=true#entry1198WriteComment">댓글 쓰기</a></strong></p>Lets' Encrypt로 무료로 HTTPS 지원하기Outsiderhttps://blog.outsider.ne.kr/11782015-12-06T05:13:39+09:002015-12-06T05:00:24+09:00<p>웹에서 HTTPS는 보안을 위해서 기본적으로 지원해야 하는 부분이다. <a href="http://googlewebmastercentral.blogspot.kr/2014/08/https-as-ranking-signal.html">구글에서도 작년부터 HTTPS를 지원 여부를 사이트의 신뢰할 수 있다는 척도로 판단하고 검색 순위에서 올리겠다고 발표</a>했다. 이 블로그에서도 HTTPS를 붙이고 싶었지만, SSL 인증서를 구매해야 하다 보니 개인 블로그에서는 부담돼서 적용을 못 하고 있었다.<br />
<br></p>
<h1>Lets' Encrypt</h1>
<p><a href="https://letsencrypt.org/">Lets' Encrypt</a>는 HTTPS를 사용하기 위해 SSL을 구매해야 하는 부분이 HTTPS 보급에 방해된다고 생각해서 SSL을 무료로 제공해서 HTTPS를 보급하기 위해 작년 말에 만들어졌다. 초기에는 Mozilla, Cisco, Akamai, EFF, id entrust 등이 모여서 ISRG(Internet Security Research Group)라는 새로운 SSL 인증기관을 만들어서 올해 SSL을 무료로 제공하겠다고 발표했다. 지금은 이 <a href="https://letsencrypt.org/">Lets' Encrypt</a>에 Facebook, 워드프레스를 만드는 Automattic, shopify 등 많은 회사가 스폰서로 참여하고 있다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/8328344311.jpg" width="750" height="174" alt="Let's Encrypt 홈페이지 헤드라인" title="" /></p>
<p>올여름부터 약간씩 구체적인 내용이 나오기 시작하면서 클로즈 베타로 신청해서 진행하다가 지난 12월 3일부터 <a href="https://letsencrypt.org/2015/12/03/entering-public-beta.html">퍼블릭 베타를 시작</a>했다. 나는 클로즈 베타를 신청해서 초대권을 받았었지만 귀차니즘에 설치를 못 하고 있다가 이번에 퍼블릭 베타가 시작되어 설치하고 적용해 봤다. 설치는 <a href="https://letsencrypt.readthedocs.org/en/latest/intro.html">공식 문서</a>를 참고했다.<br />
<br></p>
<h1>Let's Encrypt 클라이언트</h1>
<p><a href="https://letsencrypt.org/">Lets' Encrypt</a>를 통해서 인증서를 발급받으려면 Let's Encrypt 클라이언트를 사용해야 한다. 아직 퍼블릭 베타이므로 클라이언트도 아직 베타 상태이지만 내 경우에는 적용을 해봤을 때 큰 문제가 없었다. 내 서버 환경은 Ubuntu 13.04이다.</p>
<pre class="line-numbers"><code class="language-bash">$ git clone https://github.com/letsencrypt/letsencrypt
</code></pre>
<p><a href="https://github.com/letsencrypt/letsencrypt">클라이언트 저장소</a>에서 소스를 다운받는다.</p>
<pre class="line-numbers"><code class="language-bash">$ ./letsencrypt-auto --help
Bootstrapping dependencies for Debian-based OSes...
Get:1 http://apt.newrelic.com newrelic Release.gpg [198 B]
Hit http://archive.ubuntu.com trusty Release.gpg
Get:2 http://apt.newrelic.com newrelic Release [3,364 B]
Get:3 http://apt.newrelic.com newrelic/non-free amd64 Packages [16.3 kB]
Get:4 http://archive.ubuntu.com trusty-updates Release.gpg [933 B]
Hit http://ppa.launchpad.net raring Release.gpg
Get:5 http://archive.ubuntu.com trusty-security Release.gpg [933 B]
...
</code></pre>
<p>다운받은 폴더에 들어가서 <code>letsencrypt-auto --help</code>를 실행하면 자동으로 관련 의존성을 다운받아서 설치한다. 의존성이 많아서 꽤 많은 시간이 걸린다. 설치를 다 한 뒤에 다시 <code>--help</code>의 내용을 보면 다음과 같다.</p>
<pre class="line-numbers"><code class="language-bash">$ ./letsencrypt-auto --help
Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt --help
letsencrypt [SUBCOMMAND] [options] [-d domain] [-d domain] ...
The Let's Encrypt agent can obtain and install HTTPS/TLS/SSL certificates. By
default, it will attempt to use a webserver both for obtaining and installing
the cert. Major SUBCOMMANDS are:
(default) run Obtain & install a cert in your current webserver
certonly Obtain cert, but do not install it (aka "auth")
install Install a previously obtained cert in a server
revoke Revoke a previously obtained certificate
rollback Rollback server configuration changes made during install
config_changes Show changes made to server config during installation
plugins Display information about installed plugins
Choice of server plugins for obtaining and installing cert:
--apache Use the Apache plugin for authentication & installation
--standalone Run a standalone webserver for authentication
(nginx support is experimental, buggy, and not installed by default)
--webroot Place files in a server's webroot folder for authentication
OR use different plugins to obtain (authenticate) the cert and then install it:
--authenticator standalone --installer apache
More detailed help:
-h, --help [topic] print this message, or detailed help on a topic;
the available topics are:
all, automation, paths, security, testing, or any of the subcommands or
plugins (certonly, install, nginx, apache, standalone, webroot, etc)
</code></pre>
<p>퍼블릭 베타 이전에는 설치시도를 안 해봤지만 관련 글을 보면 명령어가 약간은 달라진 부분이 있다. 이 명령어를 이용해서 인증서를 받아야 하는데 Let's Encrypt 클라이언트에서 설치를 위한 여러 가지 플러그인을 제공하고 있다. 그래서 <a href="https://httpd.apache.org/">Apache 웹서버</a>를 사용하고 있다면 <code>--apache</code> 옵션으로 Apache 플러그인을 사용하면 인증서 발급부터 서버 설정까지 자동으로 해주는 것으로 보인다. <a href="https://letsencrypt.readthedocs.org/en/latest/using.html#nginx">Nginx 플러그인</a>도 제공하고 있지만, 아직 실험단계로 사용을 적극적으로 추천하지 않고 클라이언트에도 기본으로 포함되어 있지 않다.</p>
<p>나 같은 경우 <a href="http://nginx.org/">nginx 웹서버</a>를 사용하고 있었으므로 플러그인을 사용하는 대신 수동 인증서 발급 후 설치하는 방법을 사용했다.<br />
<br></p>
<h1>Let's Encrypt 인증서 발급</h1>
<p>플러그인을 사용하지 않고 수동으로 인증서만 받으려면 <code>./letsencrypt-auto certonly --manual</code> 명령어를 사용하면 된다.</p>
<pre class="line-numbers"><code class="language-bash">$ ./letsencrypt-auto certonly --manual
Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: sudo /home/outsider/.local/share/letsencrypt/bin/letsencrypt certonly --manual
</code></pre>
<p>이 명령어를 실행하면 인증서발급을 위한 정보를 받기 위한 화면이 나온다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/9855484732.gif" width="750" height="234" alt="이메일을 입력받는 설치 과정" title="" /></p>
<p>먼저 인증서에 관련된 연락을 받을 이메일을 입력한다. 그다음에는 약관에 대한 동의를 물어본다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/2472367110.gif" width="750" height="220" alt="도메인을 입력받는 설치 과정" title="" /></p>
<p>인증서를 사용할 도메인을 물어본다. 여기서는 블로그에 사용할 것이므로 하나만 입력했지만 여러 도메인을 사용하려면 콤마나 공백으로 분리해서 여러 도메인을 입력하면 된다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/5827764294.gif" width="750" height="432" alt="IP 수집동의를 묻는 설치 과정" title="" /></p>
<p>마지막으로 현재 도메인이 공개적으로 수집되는 부분에 대한 안내가 나온다. 인증서만 발급받는 경우에는 운영 서버에서 직접 하지 않고 로컬에서 발급받아서 서버에 업로드 후 적용할 수도 있으므로 이 부분에 대한 안내이다. 나 같은 경우에는 운영서버에서 직접 발급을 받았으므로 Yes를 선택했다. 여기까지 완료하고 나면 다음과 같은 안내메시지가 나오고 대기상태가 된다.</p>
<pre class="line-numbers"><code class="language-bash">Make sure your web server displays the following content at
http://blog.outsider.ne.kr/.well-known/acme-challenge/6J19PJntZgEYHiGDKQp97PtdZ4KsNare1jP3dotIB2U before continuing:
6J19PJntZgEYHiGDKQp97PtdZ4KsNare1jP3dotIB2U.ez2wa0J1JFO5k_X6K6nOXT_rklKlENka8WuYTIrfVmc
If you don't have HTTP server configured, you can run the following
command on the target server (as root):
mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" v6jTNjl519uT9PQO0JKEOoiaY2mA8sy4wloh0HpMV7M.ez2wa0J1JFO5k_X6K6nOXT_rklKlENka8WuYTIrfVmc > .well-known/acme-challenge/v6jTNjl519uT9PQO0JKEOoiaY2mA8sy4wloh0HpMV7M
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"
Press ENTER to continue
</code></pre>
<p>이 단계는 내가 발급받는 인증서의 주인이 정말 나인지를 확인하는 단계이다. 이 확인 방법으로는 특정 URL에 요청을 보내서 지정된 키가 응답으로 오는지 확인하는 방법을 취한다. 위에 나온 안내대로 <code>http://blog.outsider.ne.kr/.well-known/acme-challenge/6J19PJntZgEYHiGDKQp97PtdZ4KsNare1jP3dotIB2U</code> URL로 요청을 보냈을 때 중간에 나온 <code>6J19PJntZgEYHiGDKQp97PtdZ4KsNare1jP3dotIB2U.ez2wa0J1JFO5k_X6K6nOXT_rklKlENka8WuYTIrfVmc</code>을 반환해야 이 인증단계가 마무리된다. 하단에 나온 부분은 웹서버가 따로 없는 경우 python으로 웹서버를 임시로 띄어서 이 인증단계를 하는 방법을 알려주는 것이다.</p>
<p>나 같은 경우는 nginx를 이미 사용하고 있으므로 nginx에 이 설정을 추가했다.</p>
<pre class="line-numbers"><code class="language-clike">location /.well-known {
root /home/outsider/www/well-known;
}
</code></pre>
<p>위처럼 추가하고 <code>/home/outsider/www/well-known/.well-known/acme-challenge/B-4nYiiS8NlRP4Lq4UhRZOZiREDlmSqzFiFzM6B3MAI</code> 경로에 파일을 생성했다.(파일이름이 <code>B-4nYiiS8NlRP4Lq4UhRZOZiREDlmSqzFiFzM6B3MAI</code>이다.) 그리고 이 파일에 위의 키 내용을 입력하고 nginx를 리로드해서 위 URL로 요청을 보냈을 때 정상적으로 응답이 와야 한다.</p>
<p>이 설정을 완료한 뒤에 엔터를 누르면 확인을 진행하는데 이 인증단계에 실패하면 다음과 같은 오류가 나온다.</p>
<pre class="line-numbers"><code class="language-bash">IMPORTANT NOTES:
- The following 'urn:acme:error:unauthorized' errors were reported by
the server:
Domains: blog.outsider.ne.kr
Error: The client lacks sufficient authorization
</code></pre>
<p>인증이 제대로 이뤄졌다면 다음과 같은 성공 메시지와 함께 인증서가 생성된다.</p>
<pre class="line-numbers"><code class="language-bash">IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem. Your cert
will expire on 2016-03-04. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
</code></pre>
<p>위 내용을 보면 인증서가 2016-03-04에 만료된다고 나온 것을 볼 수 있다. 한번 발급받으면 평생 쓸 수 있는 것은 아니다. <a href="https://letsencrypt.readthedocs.org/en/latest/using.html#renewal">Let's Encrypt의 인증서는 90일 동안 유효한 인증서</a>이므로 90일마다 새로 갱신을 해야 한다. 갱신에 대해서는 <a href="https://letsencrypt.readthedocs.org/en/latest/using.html#renewal">문서</a>에 안내가 되어 있는데 이제 처음 사용했으므로 아직 갱신을 해보지 않았다.(갱신은 나중에 하게 될 때 다시...) <code>/etc/letsencrypt/live/blog.outsider.ne.kr/</code> 아래를 보면 다음과 같은 파일이 생긴 것을 볼 수 있다.</p>
<pre class="line-numbers"><code class="language-clike">cert.pem -> ../../archive/blog.outsider.ne.kr/cert1.pem
chain.pem -> ../../archive/blog.outsider.ne.kr/chain1.pem
fullchain.pem -> ../../archive/blog.outsider.ne.kr/fullchain1.pem
privkey.pem -> ../../archive/blog.outsider.ne.kr/privkey1.pem
</code></pre>
<p><br></p>
<h1>nginx에 SSL 인증서 설치</h1>
<p>웹사이트에서 HTTPS를 지원하려면 앞에서 발급받은 인증서를 nginx에 설정해야 한다. nginx의 SSL 설정은 <a href="https://mozilla.github.io/server-side-tls/ssl-config-generator/">Mozilla SSL Configuration Generator</a>를 사용했다. 사용하는 웹서버와 관련 버전을 명시하면 권장하는 설정파일을 만들어 주므로 이 파일을 그대로 사용했다.</p>
<p>나 같은 경우는 nginx를 사용하고 많은 브라우저를 지원하기 위해 Intermediate를 선택했다. nginx는 1.6.2버전을 사용하고 OpenSSL 버전은 1.0.1c였다.(OpenSSL 버전 확인은 <code>openssl version</code>)</p>
<pre class="line-numbers"><code class="language-clike">server {
listen 443 ssl;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /path/to/signed_cert_plus_intermediates;
ssl_certificate_key /path/to/private_key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /path/to/dhparam.pem;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;
resolver <IP DNS resolver>;
....
}
</code></pre>
<p>여기서 몇 가지 정보는 실제 자신의 정보로 바꾸어 주어야 한다.</p>
<pre class="line-numbers"><code class="language-clike">ssl_certificate /etc/letsencrypt/live/blog.outsider.ne.kr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.outsider.ne.kr/privkey.pem;
</code></pre>
<p><code>ssl_certificate</code>와 <code>ssl_certificate_key</code>를 발급받은 파일 중에 <code>fullchain.pem</code>와 <code>privkey.pem</code>로 지정한다.</p>
<pre class="line-numbers"><code class="language-clike">ssl_dhparam /etc/letsencrypt/live/blog.outsider.ne.kr/dhparam.pem;
</code></pre>
<p>ssl_dhparam는 <code>openssl dhparam -out dhparam.pem 2048</code>명령어를 통해서 새로 생성해야 한다.</p>
<pre class="line-numbers"><code class="language-clike">ssl_trusted_certificate /etc/letsencrypt/live/blog.outsider.ne.kr/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10;
</code></pre>
<p><code>ssl_trusted_certificate</code>부분에는 앞에서 발급받은 <code>chain.pem</code> 파일을 사용하고 <code>resolver</code>에는 <a href="https://developers.google.com/speed/public-dns/">구글의 Public DNS</a>를 사용했다. 이렇게 하면 SSL 설정은 완료되었으므로 <code>server { }</code>부분 안에 서버의 관련 설정을 추가하면 된다.</p>
<p style="text-align: center;"><img src="//blog.outsider.ne.kr/attach/1/4175244625.gif" width="309" height="393" alt="브라우저에 정상적으로 표시된 SSL 인증서" title="" /></p>
<p>인증서 정보를 보면 Lets' Encrypt에서 발급받은 인증서라면서 녹색 자물쇠 표시가 예쁘게 잘 나온다. 덕분에 무료로 <a href="https://blog.outsider.ne.kr/">블로그에서도 HTTPS를 지원</a>하게 되었다. ㅎㅎ</p>
<p><strong><a href="https://blog.outsider.ne.kr/1178?commentInput=true#entry1178WriteComment">댓글 쓰기</a></strong></p>Redmine과 Apache 연동시 Passenger의 "Permission denied - /etc/redmine/default/session.yml" 오류Outsiderhttps://blog.outsider.ne.kr/5252010-09-24T03:14:28+09:002010-09-24T03:14:28+09:00Apache와 Redmine의 연동으로 <a href="http://www.modrails.com/" target="_blank">Phusion Passenger</a>를 사용하고 있습니다. Ubuntu 10.04에서는 apt-get에도 redmine이 추가되었기 때문에 apt-get으로 간단히 연결하고 Passenger를 연동하였지만(사실 이 연동에서도 꽤 헤메기는 했지만요.) 아래와 같은 오류 메시지가 나타났습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1273893736.gif" alt="웹브라우저에 나온 passenger 오류 화면" height="421" width="550" /></div><br><br>많은 정보들이 나오지만 정확한 에러메시지는 아래와 같습니다.<br><br><blockquote style="color: rgb(255, 118, 53);">Error message:<br>Permission denied - /etc/redmine/default/session.yml</blockquote><span style="color: rgb(204, 153, 0);">Redmine의 session.yml파일에 대한 권한 거부가 발생했습니다.</span><br><br><pre class="line-numbers"><code class="language-clike">
<IfModule mod_passenger.c>
PassengerRoot /usr
PassengerRuby /usr/bin/ruby
PassengerDefaultUser www-data
</IfModule>
</code></pre><br><span style="color: rgb(255, 118, 53);">/etc/apache2/mods-available/passenger.conf</span>파일에 위처럼 4번라인의 <span style="color: rgb(255, 118, 53);">PassengerDefaultUser www-data</span> 를 추가해 주면 정상적으로 오류메시지 대신에 레드마인이 동작하는 것을 볼 수 있습니다.<br><p><strong><a href="https://blog.outsider.ne.kr/525?commentInput=true#entry525WriteComment">댓글 쓰기</a></strong></p>Terminal에서 Ubuntu 업그래이드 하기Outsiderhttps://blog.outsider.ne.kr/5242011-01-22T01:28:41+09:002010-09-23T16:28:01+09:00GUI가 없이 Ubuntu에 접속하여서 Ubuntu를 업그래이드 해야할 필요가 있었습니다.<br><br><div style="padding: 10px; background-color: rgb(228, 228, 228); color: rgb(0, 0, 0);">cat /etc/issue<br>cat /etc/lsb-release</div><br>위 두 명령어중 하나를 사용해서 현재 Ubuntu의 버전을 확인할 수 있습니다. <br>그 다음에 <span style="color: rgb(204, 153, 0);"><a href="http://blog.outsider.ne.kr/346" target="_blank">apt-get</a>을 이용해서 update-manager-core를 설치합니다.</span> 일반적으로 서버버전에는 설치가 되어 있지 않은것 같습니다.<br><br><blockquote style="color: rgb(255, 118, 53);">sudo apt-get install update-manager-core</blockquote><br>이제 업그래이드를 실행합니다.<br><br><blockquote style="color: rgb(255, 118, 53);">sudo do-release-upgrade</blockquote><br>업그래이드 뒤에는 원복할 수 없으므로 신중히 해야하고 업그래이드뒤에 호환되지 않는 부분은 직접 수정해 주어야 합니다.<br><br><br>덧) 업그래이드할 버전이 없다고 나올때는 <span style="color: rgb(255, 118, 53);">/etc/update-manager/release-upgrades</span> 파일을 열어서 <span style="color: rgb(204, 153, 0);">Prompt=normal</span>로 변경해야 이용가능한 새 버전으로 업그래이드가 가능합니다. (<a href="http://www.ubuntu.com/desktop/get-ubuntu/upgrade" target="_blank">우분투 가이드 참고</a>)<br><p><strong><a href="https://blog.outsider.ne.kr/524?commentInput=true#entry524WriteComment">댓글 쓰기</a></strong></p>Ubuntu에서 sudo 명령어로 root권한 얻지 못할때Outsiderhttps://blog.outsider.ne.kr/5052010-08-13T03:29:06+09:002010-08-13T03:29:06+09:00메인OS는 아니지만 우분투를 사용한지도 좀 되긴 했지만 항상 X-window상에서만 사용하다가 보니 꽤 많은 부분이 자동설정되어 있이서 따로 의식하지 못하고 있었습니다. 서버에 설치된 우분투에서 사용할 사용자 계정을 만들고 작업을 하다가 root권한이 필요해서 sudo -s 를 입력하자 아래와 같은 오류가 발생했습니다.<br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1102176577.gif" alt="sudo -s를 실행했을때 오류가 발생하는 화면 " height="47" width="550" /></div><br>암호를 물어보는 것까지는 정상적이었으나<span style="color: rgb(204, 153, 0);"> "userid is not in the sudoers file. This incident will be reported."라는 오류메시지가 나타나면서 root권한을 획득하는 것을 실패</span>했습니다. 해당 유저명이 sudoers파일에 없다고 합니다.(사실 이 파일의 존재자체를 처음 알았습니다.)<br><br><a href="http://www.sudo.ws/sudo/sudoers.man.html" target="_blank">sudoers파일</a>은 <span style="color: rgb(204, 153, 0);">sudo명령어에 대한 설정을 다루는 파일</span>이고 이곳에 sudo명령어를 사용할 수 있는 계정을 지정할수 있습니다. 그 외에도 여러가지 설정에 대한 부분이 있으며<span style="color: rgb(255, 118, 53);"> /etc/sudoers</span> 에 위치하고 있습니다. 기본으로 지정된 내용을 보면 <span style="color: rgb(255, 118, 53);">root ALL=(ALL) ALL</span> 이라는 부분이 있는데 이 설정이 root 유저가 sudo명령어를 사용할 수 있도록 하는 부분입니다. <br><br><div class="imageblock center" style="text-align: center; clear: both;"><img src="//blog.outsider.ne.kr/attach/1/1076079823.gif" alt="sudoers 파일에 userid부붙을 추가한 화면 " height="344" width="550" /></div><br>위처럼 sudo명령어를 사용할 계정을 root처럼 추가해 주면 정상적으로 해당 계정에서 sudo 명령어를 사용할 수 있습니다. sudoers파일은 일반적인 vi등으로 편집하지 않고 <span style="color: rgb(255, 118, 53);">visudo -f /etc/sudoers</span> 명령어를 사용하면 vi와는 다른 형태의 에디터가 열리고 여기서 수정할 수 있습니다.(vi를 통해서 접근하면 읽기전용파일로 나옵니다.) 수정후에 저장할때 sudoers 설정에 대한 문법까지 체크해주기 때문에 혹시모를 문제를 위해서 visudo를 이용해서 파일을 수정합니다.<br><p><strong><a href="https://blog.outsider.ne.kr/505?commentInput=true#entry505WriteComment">댓글 쓰기</a></strong></p>