2018年12月2日 星期日

Ansible + rails + letsencrypt


First, install nginx

roles/nginx/tasks/main.yml

```yml
- name: Install nginx
  apt:
    name: nginx
    state: latest
- name: Disable default nginx config
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify:
    - Restart nginx
```

roles/nginx/handlers/main.yml


```yml
- name: Restart nginx
  service: name=nginx state=restarted
```

Then, install LetsEncrypt

roles/letsencrypt/tasks/main.yml

```yml
- name: Generate dhparams file
  shell: openssl dhparam -out {{ dhparam_pem_path }} 2048
  args:
    creates: "{{ dhparam_pem_path }}"
- name: Update apt cache
  apt: update_cache=yes cache_valid_time=86400
- name: Install depends
  apt: name={{ item }} state=latest
  with_items:
    - python
    - python-dev
    - gcc
    - dialog
    - libaugeas0
    - augeas-lenses
    - libssl-dev
    - libffi-dev
    - ca-certificates
    - python-pip
    - python-virtualenv
    - git
    - libpython-dev
    - zlib1g-dev
- name: Lets Encrypt client
  git: dest=/opt/certbot clone=yes repo=https://github.com/certbot/certbot force=yes
# Auto-renew certificates and reload nginx
- name: Add crontab to renew certificates
  cron: minute="30" hour="2" weekday="1" job="/opt/certbot/certbot-auto renew >> /var/log/le-renew.log"
- name: Add crontab to reload server
  cron: minute="35" hour="2" weekday="1" job="/etc/init.d/nginx reload"
```


Last, configure service

roles/service/tasks/main.yml

```yml
- name: Add http nginx configuration
  template:
    src: templates/http.conf.j2
    dest: /etc/nginx/sites-available/{{ service_name }}.http.conf
  notify:
    - Restart nginx
- name: Enable nginx config
  file:
    src: /etc/nginx/sites-available/{{ service_name }}.http.conf
    dest: /etc/nginx/sites-enabled/{{ service_name }}.http.conf
    state: link
  notify:
    - Restart nginx
- name: Create letsencrypt certificate
  shell: ./certbot-auto certonly --webroot --email {{ service_admin_email }} --agree-tos --webroot-path=/usr/share/nginx/html -d {{ service_host }};
  args:
    chdir: /opt/certbot
- name: Add https nginx configuration
  template:
    src: templates/https.conf.j2
    dest: /etc/nginx/sites-available/{{ service_name }}.https.conf
  notify:
    - Restart nginx
- name: Add external https nginx symlink
  file:
    src: /etc/nginx/sites-available/{{ service_name }}.https.conf
    dest: /etc/nginx/sites-enabled/{{ service_name }}.https
    state: link
  notify:
    - Restart nginx
```

with nginx http template, this will redirect all http request into https


roles/service/templates/http.conf.j2

```
server {
  listen 80;
  server_name {{ service_host }};

  root /usr/share/nginx/html;

  index index.html index.htm index.nginx-debian.html;

  location ~ /.well-known {
    allow all;
  }

  location / {
    return 301 https://$host$request_uri;
  }
}
```

also add a https template for rails


roles/service/templates/https.conf.j2

```
upstream app {
  server unix:///home/deploy/apps/waynechu_blog/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 443 ssl;
  server_name {{ service_host }};

  root /home/deploy/apps/{{ service_name }}/current/public;

  try_files $uri/index.html $uri @app;

  ssl_certificate {{ letsencrypt_ssl_dir }}/{{ service_host }}/fullchain.pem;
  ssl_certificate_key {{ letsencrypt_ssl_dir }}/{{ service_host }}/privkey.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam {{ dhparam_pem_path }};
  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: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_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_stapling on;
  ssl_stapling_verify on;

  location @app {
    proxy_pass http://app;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;
}
```

roles/service/handlers/main.yml


```yml
- name: Restart nginx
  service: name=nginx state=restarted
```


At the last, set your own vars

vars/main.yml

```yml
service_host: "example.cc"
service_name: "example"
service_admin_email: "example@gmail.com"
letsencrypt_ssl_dir: "/etc/letsencrypt/live"
dhparam_pem_path: "/home/deploy/dhparams.pem"
```


That's it, now you have a https rails web



References:

https://medium.com/@gmaliar/generating-lets-encrypt-certificates-for-nginx-using-ansible-9fd27b90993a
https://gist.github.com/mattiaslundberg/ba214a35060d3c8603e9b1ec8627d349
https://docs.ansible.com/ansible/2.5/modules/letsencrypt_module.html
https://gorails.com/guides/free-ssl-with-rails-and-nginx-using-let-s-encrypt
https://blog.frost.tw/posts/2018/05/28/Getting-started-deploy-your-Ruby-on-Rails-Part-8/

沒有留言:

張貼留言