Ansible-role-nginx-config: nginx μ—­ ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•œ SSL μ’…λ£Œμ˜ 예

에 λ§Œλ“  2020λ…„ 05μ›” 24일  Β·  13μ½”λ©˜νŠΈ  Β·  좜처: nginxinc/ansible-role-nginx-config

κΈ°λŠ₯ μš”μ²­μ΄ λ¬Έμ œμ™€ κ΄€λ ¨λ˜μ–΄ μžˆμŠ΅λ‹ˆκΉŒ?
거의. nginx둜 ssl을 μ’…λ£Œν•˜κ³  λ™μ‹œμ— μ—­ ν”„λ‘μ‹œλ‘œ μ μš©ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 그것이 κ½€ 일반적인 μ‹œλ‚˜λ¦¬μ˜€λΌκ³  μƒκ°ν•˜λ”λΌλ„ λ¬Έμ„œμ—μ„œ 이에 λŒ€ν•œ 예λ₯Ό 보지 λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

μ›ν•˜λŠ” μ†”λ£¨μ…˜ μ„€λͺ…
μ—­ ν”„λ‘μ‹œλ‘œ SSL을 μ’…λ£Œν•˜λŠ” 방법에 λŒ€ν•œ ꡬ성 예

κ³ λ €ν•œ λŒ€μ•ˆμ„ κΈ°μˆ ν•˜μ‹­μ‹œμ˜€
이 μ—­ν•  없이 SSL μ’…λ£Œμ™€ ν•¨κ»˜ nginx λ¦¬λ²„μŠ€ ν”„λ‘μ‹œλ₯Ό μ μš©ν•˜λŠ” 것을 κ³ λ €ν–ˆμŠ΅λ‹ˆλ‹€. nginxλ₯Ό μˆ˜λ™μœΌλ‘œ κ΅¬μ„±ν•˜λŠ” κ²ƒμ²˜λŸΌ 이것이 λ„ˆλ¬΄ μ–΄λ ΅λ‹€λ©΄.

documentation

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

예제λ₯Ό κ°€μ Έ μ™€μ„œ ν…œν”Œλ¦Ώ κΈ°λ³Έκ°’μ—μ„œ κ°€μ Έμ˜¨ dict 객체둜 ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€. https://github.com/nginxinc/ansible-role-nginx/blob/master/defaults/main/template.yml

이 같은:

nginx_http_template_enable: true
nginx_http_template:
  jira_mydomain_net:
    conf_file_name: jira_mydomain_net.conf
    servers:
      first:
        listen:
          listen_public:
            ip: 0.0.0.0
            port: 443
            ssl: true
        server_name: jira.mydomain.net
        ssl:
          cert: /etc/ssl/certs/jira.mydomain.net.crt
          key: /etc/ssl/private/jira.mydomain.net.key
        access_log:
          - name: combined
            location: /var/log/nginx/jira.mydomain.net_access.log
        error_log:
          location: /var/log/nginx/jira.mydomain.net_error.log
          level: warn
        reverse_proxy:
          locations:
            default:
              location: /
              proxy_pass: http://jira01.local.mydomain.net:8080

ssl μ•”ν˜Έ, dhparam, proxy_set_header 등은 κΈ°λ³Έ κ΅¬μ„±μ—μ„œ μ„€μ •ν–ˆκΈ° λ•Œλ¬Έμ— μƒλž΅ν–ˆμ§€λ§Œ μ˜ˆμ œλ‚˜ κΈ°λ³Έκ°’μ—μ„œ κ°€μ Έκ°ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. μ—…μŠ€νŠΈλ¦Όμ„ μ‚¬μš©ν•  λ•Œλ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.

λͺ¨λ“  13 λŒ“κΈ€

예제λ₯Ό κ°€μ Έ μ™€μ„œ ν…œν”Œλ¦Ώ κΈ°λ³Έκ°’μ—μ„œ κ°€μ Έμ˜¨ dict 객체둜 ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€. https://github.com/nginxinc/ansible-role-nginx/blob/master/defaults/main/template.yml

이 같은:

nginx_http_template_enable: true
nginx_http_template:
  jira_mydomain_net:
    conf_file_name: jira_mydomain_net.conf
    servers:
      first:
        listen:
          listen_public:
            ip: 0.0.0.0
            port: 443
            ssl: true
        server_name: jira.mydomain.net
        ssl:
          cert: /etc/ssl/certs/jira.mydomain.net.crt
          key: /etc/ssl/private/jira.mydomain.net.key
        access_log:
          - name: combined
            location: /var/log/nginx/jira.mydomain.net_access.log
        error_log:
          location: /var/log/nginx/jira.mydomain.net_error.log
          level: warn
        reverse_proxy:
          locations:
            default:
              location: /
              proxy_pass: http://jira01.local.mydomain.net:8080

ssl μ•”ν˜Έ, dhparam, proxy_set_header 등은 κΈ°λ³Έ κ΅¬μ„±μ—μ„œ μ„€μ •ν–ˆκΈ° λ•Œλ¬Έμ— μƒλž΅ν–ˆμ§€λ§Œ μ˜ˆμ œλ‚˜ κΈ°λ³Έκ°’μ—μ„œ κ°€μ Έκ°ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. μ—…μŠ€νŠΈλ¦Όμ„ μ‚¬μš©ν•  λ•Œλ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.

@xTrekStorex κ°€ μ™„μ „νžˆ λ§žμŠ΅λ‹ˆλ‹€. μ–΄λ–€ λ‹¨κ³„μ—μ„œλŠ” κ°€λŠ₯ν•œ 경우 SSL(자체 μ„œλͺ… μΈμ¦μ„œ μ‚¬μš©)을 ν¬ν•¨ν•˜μ—¬ Molecule ν”Œλ ˆμ΄λΆμ—μ„œ λ‹€λ£¨λŠ” λŒ€λΆ€λΆ„μ˜ μ‚¬μš© 사둀에 λŒ€ν•œ μž‘μ—… 예제λ₯Ό κ°–κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

운이 없이 μ•„λž˜μ—μ„œ 이 ꡬ성을 μƒμ„±ν•˜λ €κ³  ν•©λ‹ˆλ‹€. μ§€μ›λ˜λŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

μœ„μΉ˜ /app1/ {
proxy_pass http://localhost :6000;
}
μœ„μΉ˜ /app2/ {
proxy_pass http://localhost :5000;
}

ν™•μ‹€νžˆ μž‘λ™ν•΄μ•Όν•©λ‹ˆλ‹€. μ΅œμ‹  릴리슀 λ˜λŠ” 메인을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ? 메인에 μžˆλ‹€λ©΄ https://github.com/nginxinc/ansible-role-nginx-config/blob/main/molecule/default/converge.yml#L153 -L290 -- proxy_pass κ°€ μžˆλŠ” 두 개의 μœ„μΉ˜ 블둝이 μžˆλŠ” 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. location 및 proxy_pass 에 λŒ€ν•΄ μ–ΈκΈ‰ν•œ 값을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (μ°Έκ³ : μƒˆ 문제λ₯Ό λ§Œλ“€κ³  싢을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. κ·€ν•˜μ˜ μ§ˆλ¬Έμ€ μ œκ°€ 말할 수 μžˆλŠ” ν•œ ssl 와 관련이 μ—†μŠ΅λ‹ˆλ‹€.)

λ˜ν•œ λ‹¨μˆœ μ—­λ°©ν–₯ ν”„λ‘μ‹œλ₯Ό ꡬ성할 수 μ—†μŠ΅λ‹ˆλ‹€. μœ„μ˜ μ˜ˆμ—μ„œ λ‚˜λŠ” μΈμ‹ν•˜μ§€ λͺ»ν•œλ‹€.

reverse_proxy:

λΆ€λΆ„.

λ‚΄κ°€ μ •μ˜ν•œ μ„œλ²„μ—μ„œ root λŒ€μ‹  proxy_passλ₯Ό μ‚¬μš©ν•˜λ €κ³  ν•˜λ©΄

TemplateAssertionError: no test named 'boolean'

μž‘μ—… 예λ₯Ό λ“€μ–΄ μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

reverse_proxy μ„Ήμ…˜μ΄ 더 이상 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이제 main (및 0.4.0 )μ—μ„œ 찾을 수 μžˆλŠ” proxy μ‚¬μ „μœΌλ‘œ λ¦¬νŒ©ν† λ§λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이전 λŒ“κΈ€μ—μ„œ λΆ„μž μ˜ˆμ‹œλ₯Ό ν™•μΈν•˜μ…¨λ‚˜μš”? λ˜ν•œ proxy_pass λŠ” μ„œλ²„ μ»¨ν…μŠ€νŠΈ λ‚΄μ—μ„œ ν—ˆμš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 항상 location https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass μ•ˆμ— μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

μ˜ˆμ‹œ:

nginx_config_http_template_enable: true
    nginx_config_http_template:
      - template_file     : http/default.conf.j2
        conf_file_name    : '{{ my_server_name }}.conf'
        conf_file_location: /etc/nginx/conf.d/
        servers:
          - listen:
              - port: 443
                ssl : true
                opts: []
            server_name: '{{ my_server_name }}'
            ssl:
              cert                 : '/etc/ssl/certs/{{ my_ssl_prefix }}.nginx.bundle.crt'
              key                  : '/etc/ssl/private/{{ my_ssl_prefix }}.key'
              protocols            : '{{ NGINX_PROTOCOLS }}'
              prefer_server_ciphers: true
              ciphers              : '{{ NGINX_CIPHERS   }}'
              stapling             : true
              stapling_verify      : true
            autoindex : false
            locations :
              - location: /
                root    : '{{ my_root_folder }}'
              - location: /backend
                proxy_pass: http://127.0.0.1:8080/
                proxy:
                  set_header:
                     - field: Host
                       value: $host
                     - field: X-Real-IP
                       value: $remote_addr
                     - field: X-Forwarded-For
                       value: $proxy_add_x_forwarded_for
                     - field: X-Forwarded-Proto
                       value: $scheme

κ·Έ κ²°κ³Ό

failed: [testing-snap05.MYDOMAIN.TLD] (item={'template_file': 'http/default.conf.j2', 'conf_file_name': 'testing-snap05.staging.MYDOMAIN.TLD.conf', 'conf_file_location': '/etc/nginx/conf.d/', 'servers': [{'listen': [{'port': 443, 'ssl': True, 'opts': []}], 'server_name': 'testing-snap05.staging.MYDOMAIN.TLD', 'ssl': {'cert': '/etc/ssl/certs/star.staging.MYDOMAIN.TLD.nginx.bundle.crt', 'key': '/etc/ssl/private/star.staging.MYDOMAIN.TLD.key', 'protocols': 'TLSv1.3', 'prefer_server_ciphers': True, 'ciphers': 'HIGH:!aNULL:!MD5', 'stapling': True, 'stapling_verify': True}, 'autoindex': False, 'locations': [{'location': '/', 'root': '/usr/share/nginx/html'}, {'location': '/backend', 'proxy_pass': 'http://127.0.0.1:8080/', 'proxy': {'set_header': [{'field': 'Host', 'value': '$host'}, {'field': 'X-Real-IP', 'value': '$remote_addr'}, {'field': 'X-Forwarded-For', 'value': '$proxy_add_x_forwarded_for'}, {'field': 'X-Forwarded-Proto', 'value': '$scheme'}]}}]}]}) => {"ansible_loop_var": "item", "changed": false, "item": {"conf_file_location": "/etc/nginx/conf.d/", "conf_file_name": "testing-snap05.staging.MYDOMAIN.TLD.conf", "servers": [{"autoindex": false, "listen": [{"opts": [], "port": 443, "ssl": true}], "locations": [{"location": "/", "root": "/usr/share/nginx/html"}, {"location": "/backend", "proxy": {"set_header": [{"field": "Host", "value": "$host"}, {"field": "X-Real-IP", "value": "$remote_addr"}, {"field": "X-Forwarded-For", "value": "$proxy_add_x_forwarded_for"}, {"field": "X-Forwarded-Proto", "value": "$scheme"}]}, "proxy_pass": "http://127.0.0.1:8080/"}], "server_name": "testing-snap05.staging.MYDOMAIN.TLD", "ssl": {"cert": "/etc/ssl/certs/star.staging.MYDOMAIN.TLD.nginx.bundle.crt", "ciphers": "HIGH:!aNULL:!MD5", "key": "/etc/ssl/private/star.staging.MYDOMAIN.TLD.key", "prefer_server_ciphers": true, "protocols": "TLSv1.3", "stapling": true, "stapling_verify": true}}], "template_file": "http/default.conf.j2"}, "msg": "TemplateAssertionError: no test named 'boolean'"}

였λ₯Έμͺ½. μ΅œμ‹  λ²„μ „μ˜ Jinja2둜 μ—…λ°μ΄νŠΈν•΄ λ³΄μ„Έμš”. ν…œν”Œλ¦Ώμ΄ μ œλŒ€λ‘œ μž‘λ™ν•˜λ €λ©΄ Jinja2 2.11.x κ°€ ν•„μš”ν•©λ‹ˆλ‹€. 이것은 https://github.com/nginxinc/ansible-role-nginx-config/issues/94μ—μ„œ 찾은 였λ₯˜μ™€ κ°€μž₯ 관련이 μžˆμŠ΅λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€. Ubuntu 20.04용 νŒ¨ν‚€μ§€λ‘œ μ‘΄μž¬ν•©λ‹ˆκΉŒ? 그렇지 μ•ŠμœΌλ©΄ ꢌμž₯λ˜λŠ” μ—…λ°μ΄νŠΈ 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

Jinja2λŠ” 파이썬 νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€. pip install -U Jinja2 을(λ₯Ό) μ‹€ν–‰ν•΄ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. https://jinja.palletsprojects.com/en/2.11.x/intro/#installation μ—μ„œ μžμ„Έν•œ λ‚΄μš©μ„ 읽을 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš”,

python 2.7 및 ansible 2.9.6μ—μ„œ λ™μΌν•œ λ¬Έμ œκ°€ 있음:
"TemplateAssertionError: no test named 'boolean'"

python 3.6 및 2.9.6μ—μ„œλŠ” λͺ¨λ“  것이 잘 μž‘λ™ν•©λ‹ˆλ‹€.

λ³€μˆ˜:

nginx_config_http_template_enable: true
nginx_config_http_template:
  - template_file: http/default.conf.j2
    conf_file_name: 50_example.com.conf
    conf_file_location: /etc/nginx/conf.d/

    servers:
      - listen:
          - ip: 0.0.0.0
            port: 80

          - ip: 0.0.0.0
            port: 443
            ssl: true

        ssl:    
          cert: /etc/pki/tls/certs/example.com.crt
          key: /etc/pki/tls/private/example.com.key

        server_name: example.com
        error_page: /usr/share/nginx/html
        autoindex: false
        http_demo_conf: false

        access_log:
          - name: json
            location: /var/log/nginx/example.com-access.json.log
        error_log:
          level: warn
          location: /var/log/nginx/example.com-error.log

        locations:
          - location: /
            proxy_pass: http://127.0.0.1
            proxy:
              bind: false
              set_header:
                - field: Host
                  value: $host
                - field: X-Forwarded-For
                  value: $proxy_add_x_forwarded_for
                - field: X-Real-IP
                  value: $remote_addr
                - field: REMOTE_ADDR
                  value: $remote_addr

κ²°κ³Ό:

+#
+# Ansible managed
+#
+
+
+
+
+server {
+    listen 0.0.0.0:80;
+    listen 0.0.0.0:443 ssl;
+    server_name example.com;
+    ssl_certificate /etc/pki/tls/certs/example.com.crt;
+    ssl_certificate_key /etc/pki/tls/private/example.com.key;
+    location / {
+        proxy_bind off;
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header REMOTE_ADDR $remote_addr;
+
+        proxy_pass http://127.0.0.1;
+
+    }
+    # redirect server error pages to the static page /50x.html
+    #
+    error_page   500 502 503 504  /50x.html;
+    location = /50x.html {
+        root   /usr/share/nginx/html;
+    }
+    access_log  /var/log/nginx/example.com-access.json.log  json;
+    error_log /var/log/nginx/example.com-error.log warn;
+}

Jinja2λ₯Ό μ—…λ°μ΄νŠΈν•΄ λ³΄μ„Έμš”. μ΅œμ‹  릴리슀(v2.11)λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

@alessfg κ°μ‚¬ν•©λ‹ˆλ‹€!

빨간색 좜λ ₯이 μ—†μ—ˆκΈ° λ•Œλ¬Έμ— μ‹€μ œλ‘œ Jinja2λ₯Ό 둜컬둜 μ—…λ°μ΄νŠΈν•˜λŠ” 데 λ¬Έμ œκ°€ μžˆλ‹€λŠ” 것을 μ•Œμ•„μ°¨λ¦¬μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

bash-3.2$ pip install -U Jinja2
Collecting Jinja2
  Using cached https://files.pythonhosted.org/packages/7e/c2/1eece8c95ddbc9b1aeb64f5783a9e07a286de42191b7204d67b7496ddf35/Jinja2-2.11.3-py2.py3-none-any.whl
Requirement not upgraded as not directly required: MarkupSafe>=0.23 in /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages (from Jinja2) (0.23)
Installing collected packages: Jinja2
  Found existing installation: Jinja2 2.10.1
    Uninstalling Jinja2-2.10.1:
      Successfully uninstalled Jinja2-2.10.1
  Rolling back uninstall of Jinja2

You are using pip version 10.0.0, however version 20.3.4 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

Python 2.7 및 Jinja2 2.11.3이 μžˆλŠ” κΉ¨λ—ν•œ virtualenvμ—μ„œλŠ” λͺ¨λ“  것이 잘 μž‘λ™ν•©λ‹ˆλ‹€.

(py27) bash-3.2$ pip freeze 
ansible==2.9.6
cffi==1.14.5
cryptography==3.3.2
enum34==1.1.10
ipaddress==1.0.23
Jinja2==2.11.3
MarkupSafe==1.1.1
pycparser==2.20
PyYAML==5.4.1
six==1.15.0
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰