【问题标题】:Nginx if statement on ssl certificatesNginx if 对 ssl 证书的声明
【发布时间】:2018-03-23 14:46:19
【问题描述】:

我想知道是否可以对 nginx ssl 证书(或配置的任何其他部分)执行 if 语句

if ( -f /etc/letsencrypt/live/{domain}/cert.pem ) {
  ssl_certificate /etc/letsencrypt/live/{domain}/cert.pem;
  ssl_certificate_key /etc/letsencrypt/live/{domain}/privkey.pem;
}

这会产生以下错误:

nginx: [emerg] "ssl_certificate" directive is not allowed here in /etc/nginx/sites-enabled/app.phase.be.conf:7

我查看了文档和谷歌,得出的结论是这不能完成。仅用于重写。

在 Letsencrypt 颁发证书之前,是否有另一种方法可以完全忽略 ssl 证书或用自签名证书替换它们。这是一个自动化的过程,如果Nginx被另一个进程触发(例如修改过的服务器块),Nginx可以随时重新加载

编辑:

感谢@Chris 指出正确的方向!

我最终所做的看起来像这样,但这是精简和简化的。

config = Config().read()
logging.basicConfig(filename=config['settings']['log_file'],
                      filemode='a',
                      format='%(asctime)s [ %(levelname)s ] - %(message)s',
                      datefmt='%m/%d/%Y  %H:%M:%S',
                      level=config['settings']['log_level'])

class NginxHandler(PatternMatchingEventHandler):
    patterns = ["*.conf", "*.cnf"]

    def process(self, event):
        logging.info('PROXY-LISTENER: Vhost configuration has changed reloading Nginx')
        time.sleep(1)
        subprocess.call(['nginx', '-s', 'reload'])

    def on_modified(self, event):
        self.process(event)

    # def on_created(self, event):
    #     self.process(event)

    def on_deleted(self,event):
        self.process(event)

class SslHandler(PatternMatchingEventHandler):
    patterns = ["*.pem", "*.key", "*.crt"]

    def process(self, event):
        logging.info('PROXY-LISTENER: SSL certificate updated, reloading nginx')
        subprocess.call(['nginx', '-s', 'reload'])

    def on_modified(self, event):
        self.process(event)

    # def on_created(self, event):
    #     self.process(event)

    def on_deleted(self,event):
        self.process(event)

logging.info('PROXY-LISTENER: Starting Proxy Listener')
observer = Observer()
observer.schedule(NginxHandler(), path='/etc/nginx/sites-enabled/')
observer.schedule(SslHandler(), path='/etc/nginx/ssl/', recursive=True)
observer.start()
logging.info('PROXY-LISTENER: Nginx vhost watcher started')
logging.info('PROXY-LISTENER: Nginx certificate watcher started')

这会监视两个目录的变化并相应地执行操作。在创建新的虚拟主机时,Ssl().add_temp_cert() 会被调用并创建所需的符号链接。

def add_temp_cert(self, vhost):
    '''
    Create a symbolic link to provide a temporary ssl certificate 
    for the new vhost untill a valid one has been installed
    '''
        subprocess.call(['mkdir', '-p', '/etc/nginx/ssl/' + self.domain])
        subprocess.call(['ln', '-s', '/etc/nginx/ssl/nginx.crt', '/etc/nginx/ssl/' + domain + '/cert.pem'])
        subprocess.call(['ln', '-s', '/etc/nginx/ssl/nginx.key', '/etc/nginx/ssl/' + domain + '/privkey.pem'])
    else:
        self.add_cert(vhost)

def add__letsencrypt_cert(self, vhost):
    '''
    Create a symbolic link to /etc/nginx/ssl for the obtained ssl certificate
    '''
        subprocess.call(['rm', '-f', '/etc/nginx/ssl/' + self.domain + '/'])
        subprocess.call(['ln', '-s', '/etc/letsencrypt/live/' + self.domain + '/', '/etc/nginx/ssl/' + self.domain + '/'])

【问题讨论】:

标签: ssl nginx vhosts lets-encrypt


【解决方案1】:

如果您已经存在触发 nginx 重新加载的进程/脚本,则使用 linux 符号链接

server {
  ...

  ssl_certificate      /etc/nginx/ssl/link-cert.pem;
  ssl_certificate_key  /etc/nginx/ssl/link-privkey.pem;

  ...
}

nginx-ssl-reload.sh

#!/bin/bash

# exit on errors
set -e

# remove existing links
rm /etc/nginx/ssl/link-cert.pem
rm /etc/nginx/ssl/link-privkey.pem

DOMAIN="anthum.com"
# link files specified in nginx.conf to real cert files
if [ -f "/etc/letsencrypt/live/$DOMAIN/cert.pem" ]; then
  ln -s "/etc/letsencrypt/live/$DOMAIN/cert.pem"    /etc/nginx/ssl/link-cert.pem
  ln -s "/etc/letsencrypt/live/$DOMAIN/privkey.pem" /etc/nginx/ssl/link-privkey.pem
else
  ln -s /etc/nginx/ssl/self-signed.crt  /etc/nginx/ssl/link-cert.pem
  ln -s /etc/nginx/ssl/self-signed.key  /etc/nginx/ssl/link-privkey.pem
fi


# Reload nginx
nginx -s reload

【讨论】:

  • 没有考虑外部脚本,因为我认为重新加载不是一个选项。但不错的收获
【解决方案2】:

只需硬编码一些默认的自签名证书,并允许 Certbot 的 Nginx 插件在您运行它时重写 ssl_certificate 语句。例如,Ubuntu 和 Debian 默认会生成一个自签名的“snakeoil”密钥和证书:

ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate /etc/ssl/private/ssl-cert-snakeoil.key;

如果您自己运行certbot,它应该会检测到 Nginx 并提供为您自动配置 Nginx。您也可以使用--nginx 明确指定您要使用 Nginx 自动配置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 2016-01-04
    • 2017-11-21
    • 2016-10-25
    • 2020-08-16
    相关资源
    最近更新 更多