All Products
Search
Document Center

Certificate Management Service:Install an SSL certificate on an Nginx or Tengine server (Linux)

Last Updated:Nov 11, 2025

This topic describes how to install an SSL certificate on an Nginx or Tengine server in a Linux environment to enable secure access over HTTPS. It covers downloading and uploading the certificate, configuring the server, setting key parameters, verifying the installation, and troubleshooting common issues.

Important

If you have questions, contact your account manager for assistance.

Usage notes

Before you begin, make sure that you meet the following requirements:

  • Certificate status: You have an SSL certificate issued by a trusted certificate authority. If the certificate is about to expire or has expired, you must first renew the SSL certificate.

  • Domain name matching: Make sure that the certificate matches all domain names that you want to secure. To add or modify domain names, you can Purchase a commercial certificate or Append and replace domain names.

    • Exact-match domain name: Applies only to the specified domain.

      • example.com protects only example.com.

      • www.example.com protects only www.example.com.

    • Wildcard domain name: Applies only to its first-level subdomains.

      • *.example.com applies to first-level subdomains such as www.example.com and a.example.com.

      • *.example.com does not protect the root domain example.com or multi-level subdomains such as a.b.example.com.

    Note

    To match multi-level subdomains, the Bound Domains field must contain the exact domain, such as a.b.example.com, or a corresponding wildcard domain, such as *.b.example.com.

  • Server permissions: You need a root account or an account with sudo privileges.

  • Domain name resolution: The domain's DNS record is configured and resolves to the server's public IP address.

Procedure

Step 1: Prepare the SSL certificate

  1. Go to the SSL Certificates page. In the Actions column for the target certificate, click Download Certificate. On the Download tab, download the certificate where the Server Type is Nginx.

  2. Unzip the downloaded certificate package:

    • If the package contains a certificate file (.pem) and a private key file (.key), save both files. You will need them for deployment.

    • If the package contains only a certificate file (.pem) and not a private key file (.key), you must deploy the certificate with the private key file that you saved locally.

      Note

      If you used a tool such as OpenSSL or Keytool to generate a Certificate Signing Request (CSR) file when applying for a certificate, the private key file was saved only on your local machine. The downloaded certificate package does not include the private key. If the private key is lost, the certificate is unusable. You must purchase a commercial certificate again and generate a new CSR and private key.

  3. Upload the extracted certificate file (.pem) and private key file (.key) to the server. Store them in a secure directory, such as the /etc/ssl/cert directory.

    Note

    You can use the local file upload feature of a remote logon tool, such as PuTTY, XShell, or WinSCP, to upload files. If you are using an Alibaba Cloud Elastic Compute Service (ECS) instance, for more information about how to upload files, see Upload or download files.

Step 2: Configure the system and network environment

Ensure your security group and system firewall allow inbound traffic on the HTTPS port (443).

  1. Run the following command in the server terminal to check whether port 443 is open:

    RHEL/CentOS

    command -v nc > /dev/null 2>&1 || sudo yum install -y nc
    # Replace <your_server_public_ip> with the public IP address of your server.
    sudo ss -tlnp | grep -q ':443 ' || sudo nc -l 443 & sleep 1; nc -w 3 -vz <your_server_public_ip> 443

    If the output is Ncat: Connected to <your_server_public_ip>:443, port 443 is open. Otherwise, open port 443 in the security group and firewall.

    Debian/Ubuntu

    command -v nc > /dev/null 2>&1 || sudo apt-get install -y netcat
    # Replace <your_server_public_ip> with the public IP address of your server.
    sudo ss -tlnp | grep -q ':443 ' || sudo nc -l -p 443 & sleep 1; nc -w 3 -vz <your_server_public_ip> 443

    If the output is Connection to <your_server_public_ip> port [tcp/https] succeeded! or [<your_server_public_ip>] 443 (https) open, port 443 is open. Otherwise, open port 443 in the security group and firewall.

  2. Open port 443 in your security group configuration.

    Important

    If your server is deployed on a cloud platform, make sure that its security group allows inbound traffic on TCP port 443. Otherwise, the service will be inaccessible. The following steps use Alibaba Cloud ECS as an example. For other cloud platforms, refer to their official documentation.

    Go to the Elastic Compute Service (ECS) instances page and click the target instance name to go to the instance details page. For more information, see Add a security group rule to add a rule in the Security Group section with Authorization Policy set to Allow, Protocol Type to TCP, Destination Port Range to HTTPS (443), and Authorization Object to Anywhere (0.0.0.0/0).

  3. Open port 443 in your firewall.

    Run the following command to identify the active firewall service on your system:

    if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet firewalld; then
        echo "firewalld"
    elif command -v ufw >/dev/null 2>&1 && sudo ufw status | grep -qw active; then
        echo "ufw"
    elif command -v nft >/dev/null 2>&1 && sudo nft list ruleset 2>/dev/null | grep -q 'table'; then
        echo "nftables"
    elif command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet iptables; then
        echo "iptables"
    elif command -v iptables >/dev/null 2>&1 && sudo iptables -L 2>/dev/null | grep -qE 'REJECT|DROP|ACCEPT'; then
        echo "iptables"
    else
        echo "none"
    fi

    If the output is none, no further action is required. Otherwise, run the corresponding command below based on the output (firewalld, ufw, nftables, or iptables) to open port 443:

    firewalld

    sudo firewall-cmd --permanent --add-port=443/tcp && sudo firewall-cmd --reload

    ufw

    sudo ufw allow 443/tcp

    nftables

    sudo nft add table inet filter 2>/dev/null
    sudo nft add chain inet filter input '{ type filter hook input priority 0; }' 2>/dev/null
    sudo nft add rule inet filter input tcp dport 443 counter accept 2>/dev/null

    iptables

    sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

    To make sure that the iptables rules persist after a system reboot, run the following commands:

    RHEL/CentOS
    sudo yum install -y iptables-services
    sudo service iptables save
    Debian/Ubuntu
    sudo apt-get install -y iptables-persistent
    sudo iptables-save | sudo tee /etc/iptables/rules.v4 >/dev/null

Step 3: Install the SSL certificate on Nginx

  1. Install the SSL module for Nginx.

    Run the following command. If the output is --with-http_ssl_module, the SSL module is already installed. Otherwise, install it.

    nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'
    Note

    If the system prompts nginx: command not found, run the command using the actual installation path of Nginx, such as /usr/local/nginx/sbin/nginx. For example: /usr/local/nginx/sbin/nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'.

    Select the installation method for the SSL module based on how Nginx was installed (compiled from source or installed using a package manager):

    Important
    • During the process of adding the SSL module, the Nginx service may be briefly interrupted, which can affect your online business.

    • Always back up your Nginx configurations and data first. Perform these changes during off-peak hours. After the modification is complete, restore the configuration and verify that the service is running normally.

    Using a package manager

    Run the following command in the server terminal:

    RHEL/CentOS

    # Add the official Nginx repository.
    sudo tee /etc/yum.repos.d/nginx.repo <<EOF
    [nginx-stable]
    name=nginx stable repo
    baseurl=https://nginx.org/packages/centos/\$releasever/\$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    EOF
    
    # Upgrade Nginx.
    sudo yum upgrade nginx

    Debian/Ubuntu

    # Upgrade Nginx.
    sudo apt-get update
    sudo apt-get install --only-upgrade nginx
    Compiling from source
    1. Install dependencies.

      RHEL/CentOS

      sudo yum install -y gcc pcre-devel zlib-devel openssl-devel

      Debian/Ubuntu

      sudo apt-get update
      sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
    2. View the current Nginx compilation parameters.

      nginx -V

      Record all parameters after configure arguments:. You will need to use all of them when you recompile.

    3. Download the source code package that matches the current Nginx version.

      Run nginx -v to view the current Nginx version (1.14.2 is used as an example). Then, download and extract the source code package for the current Nginx version:

      wget http://nginx.org/download/nginx-1.14.2.tar.gz
      tar -zxvf nginx-1.14.2.tar.gz
      cd nginx-1.14.2
    4. Recompile Nginx to add the SSL module.

      Append --with-http_ssl_module to your recorded configure arguments: and recompile:

      # Note: You must keep all original parameters to avoid losing existing functional modules.
      ./configure <Original parameters> --with-http_ssl_module
      make
      Note

      If you encounter the error error: ‘ENGINE_by_id’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations] when you run make, this indicates that some Nginx code has been marked as deprecated in OpenSSL 3.0 or later, and the compiler is treating it as an error. You can ignore these warnings and complete the compilation by running: make CFLAGS='-Wno-error=deprecated-declarations'.

    5. Replace the Nginx executable file.

      Back up the original Nginx executable file (the path /usr/local/nginx/sbin/nginx is used as an example):

      # Replace /usr/local/nginx/sbin/nginx with the actual path of the nginx file.
      sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

      Overwrite the original Nginx executable file:

      # Replace /usr/local/nginx/sbin/nginx with the actual path of the nginx file.
      sudo cp objs/nginx /usr/local/nginx/sbin/nginx
    6. Verify that the SSL module is installed.

      nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'

      If the output is --with-http_ssl_module, the SSL module is installed.

  2. Configure the SSL certificate and private key file in Nginx.

    Important

    This topic uses Nginx version 1.14.2 and the configuration file path /etc/nginx/nginx.conf as an example. The steps also apply to Tengine, which is compatible with Nginx configurations. To find your configuration file, see How can I find the active Nginx configuration file (nginx.conf) on a Linux server?.

    1. Run the following command to open the configuration file.

      sudo vim /etc/nginx/nginx.conf
    2. Add a server block to listen on port 443.

      Create a new server block for HTTPS by copying the existing one for port 80. In the new block, change listen 80 to listen 443 ssl and add the SSL certificate configuration, including the ssl_certificate and ssl_certificate_key directives. Keep the other fields unchanged.

      # Original server block listening on port 80
      server {
          listen 80;
          server_name yourdomain www.yourdomain;
          
          # Other configurations
          location / {
              proxy_pass http://127.0.0.1:8000;
          }
      }
      
      # CNew server block for HTTPS.
      server {
          # Change the original 'listen 80' to 'listen 443 ssl'.
          listen 443 ssl;
          # Original server_name. You can add more domain names supported by the current certificate.
          server_name yourdomain www.yourdomain;
          
          # ======================= Start of certificate configuration =======================
          # Specify the certificate file (the intermediate certificate can be appended to this .pem file). Replace /etc/ssl/cert/ssl.pem with the absolute path of your certificate file.
          ssl_certificate /etc/ssl/cert/ssl.pem;
          # Specify the private key file. Replace /etc/ssl/cert/ssl.key with the absolute path of your private key file.
          ssl_certificate_key /etc/ssl/cert/ssl.key;
          # Configure the SSL session cache to improve performance.
          ssl_session_cache shared:SSL:1m;
          # Set the SSL session timeout period.
          ssl_session_timeout 5m;
          # Customize the TLS protocol types and cipher suites to use (the following is an example configuration; evaluate whether you need to configure it).
          ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
          # Specify the allowed TLS protocol versions. Higher TLS versions provide better security for HTTPS communication, but have poorer browser compatibility than lower TLS versions.
          ssl_protocols TLSv1.2 TLSv1.3;
          # Prioritize the cipher suites specified by the server.
          ssl_prefer_server_ciphers on;
          # ======================= End of certificate configuration =======================
         
          # Other configurations
      }
    3. Optional: Set up automatic redirection from HTTP to HTTPS. Add the return directive to the original server block that listens on port 80.

      # Original server block listening on port 80
      server {
          listen 80;
          server_name yourdomain www.yourdomain;
              
          # Set up automatic redirection from HTTP to HTTPS.
          return 301 https://$host$request_uri;
          
          # Other original configurations can be removed as they will no longer be reached.
      }
    4. Run the following command to check the configuration file for syntax errors. If the output is syntax is ok and test is successful, the test passed. Otherwise, correct the configuration based on the error messages until the test passes.

      sudo nginx -t -c /etc/nginx/nginx.conf
  3. Reload the Nginx service.

    Important

    This topic assumes Nginx is started with the default configuration path. If you have a custom installation path or configuration file, adjust the commands and paths accordingly.

    Select the appropriate operation based on whether Nginx is running:

    If the Nginx service is running

    Run the following command to reload the Nginx configuration without restarting the service or interrupting existing connections. If the reload fails, see the FAQ for troubleshooting.

    sudo nginx -s reload

    If the Nginx service is not running

    Run the following command to start the Nginx service.

    nginx

Step 4: Verify the deployment

  1. Access your domain over HTTPS in a web browser. For example, https://yourdomain. Replace yourdomain with your actual domain.

  2. If a lock icon appears in the browser's address bar, the certificate is deployed successfully. If you encounter access errors or the lock icon does not appear, clear your browser cache or try again in incognito (privacy) mode.

    image

    Starting from version 117, the image icon in the Chrome address bar has been replaced with a new image icon. Click this icon to view the lock information.

Note

If the issue persists, see the FAQ for troubleshooting.

Going live

When you deploy to a production environment, follow these best practices to enhance security, stability, and maintainability:

  • Run as a non-administrator user:

    Create a dedicated, low-privilege system user for the application. Never run the application with an account that has administrator privileges.

    Note

    A recommended approach is to configure SSL at the gateway layer. This involves deploying the certificate on a Server Load Balancer (SLB). The gateway terminates the HTTPS traffic and forwards the decrypted HTTP traffic to the backend application.

  • Externalize credential management:

    Never hard-code passwords or other sensitive information in your code or configuration files. Use environment variables, Vault, or a cloud provider's key management service to inject credentials.

  • Enforce HTTP to HTTPS redirection:

    Redirect all HTTP traffic to HTTPS to prevent man-in-the-middle attacks.

  • Configure modern TLS protocols:

    Disable old and insecure protocols (such as SSLv3, TLSv1.0, and TLSv1.1) in your server configuration. Enable only TLSv1.2 and TLSv1.3.

  • Monitor certificates and automate renewal:

    After you deploy the certificate, enable domain monitoring. Alibaba Cloud automatically checks the certificate validity period and sends renewal reminders before expiration to help you renew in a timely manner and avoid service interruption. For detailed instructions, see Purchase and enable public domain name monitoring.

FAQ

Why is my certificate not working or HTTPS inaccessible after installation or update?

This issue is often caused by one of the following configuration problems. Check them in order:

  • Port 443 blocked: The server's security group or firewall does not have port 443 open. See Configure the system and network environment.

  • Domain mismatch: The domain you are accessing is not listed in the certificate's Bound Domains. See Domain name matching.

  • Nginx not reloaded: The Nginx service was not reloaded after you modified the configuration file. See Reload the Nginx service for instructions.

  • Incorrect certificate configuration: The certificate files were not replaced correctly, or the Nginx configuration points to the wrong file path. Ensure the paths for ssl_certificate and ssl_certificate_key are correct.

  • Missing certificate on other services: If your domain uses services such as a Content Delivery Network (CDN), Server Load Balancer (SLB), or Web Application Firewall (WAF), the certificate must also be installed on those services. See Certificate deployment locations when traffic passes through multiple Alibaba Cloud services.

  • Incomplete deployment on multiple servers: If your domain's DNS resolves to multiple servers, the certificate must be installed on all of them.

What is the correct way to update or replace an SSL certificate on an Nginx server?

Follow these steps to update your certificate without downtime:

  1. Back up old files: Back up your current certificate (.pem) and private key (.key) files on the server.

  2. Get new files: Download the new certificate and private key files from your Certificate Management Service console.

  3. Replace files: Upload the new files to your server, overwriting the old ones. Ensure the new files have the exact same path and filename as the ones specified in your Nginx configuration.

  4. Reload Nginx: Reload the Nginx service to apply the new certificate.

How can I find the active Nginx configuration file (nginx.conf) on a Linux server?

First, check if a custom configuration file is being used at runtime.

  1. In the terminal, run ps -ef | grep '[n]ginx: master' | grep -- ' -c '. If the output is similar to -c /etc/nginx/custom.conf, Nginx is using the /etc/nginx/custom.conf configuration file.

  2. If no output similar to the one described in step 1, Nginx is using its default compiled path. Run nginx -V 2>&1 | grep -oP -- '--conf-path=[^ ]*' to view the default configuration file path. For example, --conf-path=/etc/nginx/nginx.conf indicates that /etc/nginx/nginx.conf is used by default.

How to disable TLSv1.0 and TLSv1.1 in Nginx to prevent some browsers from showing a "certificate does not meet standards" message?

Modify the ssl_protocols directive in your Nginx configuration file to only TLSv1.2 and TLSv1.3 for ssl_protocols.

The final configuration should be ssl_protocols TLSv1.2 TLSv1.3;. This disables the insecure TLSv1.0 and TLSv1.1. After you modify the configuration, run nginx -s reload to apply the settings.

Why does nginx -t fail with the error bind() to 0.0.0.0:443 failed (98: Address already in use)?

This error means another process is already listening on port 443, preventing Nginx from binding to it.

  1. Find the conflicting process: Run the sudo ss -tlnp | grep :443 command to identify which process is using port 443:

  2. Stop or reconfigure the process: Once identified, you must either stop the conflicting process (such as another web server like Apache or a stuck Nginx instance) or reconfigure it to use a different port.

Why is my Nginx configuration test failing with the error: cannot load certificate "/etc/nginx/ssl/domain.pem" : BIO_new_file() failed?

This error means Nginx cannot find the certificate file at the location specified in your configuration.

To fix this, correct the path in the ssl_certificate or ssl_certificate_key directive within your Nginx configuration file to be the correct, absolute path to your certificate file.

Why does reloading Nginx fail with the error the "ssl" parameter requires ngx_http_ssl_module?

This error indicates that your Nginx build is missing the SSL module, which is required to handle HTTPS traffic.

You must install or recompile Nginx with the ngx_http_ssl_module enabled. For instructions, see Install the SSL module for Nginx.

When reloading Nginx, why do I get a No such file or directory:fopen('/cert/3970497_demo.aliyundoc.com.pem','r') error pointing to my certificate file?

This error means the file path specified for ssl_certificate or ssl_certificate_key in your Nginx configuration is incorrect.

To resolve this, verify that the paths in your configuration file are the correct, absolute paths to your .pem and .key files and that the files exist at that location.

Why does reloading Nginx fail with a permission denied error when trying to read my SSL certificate files?

This error occurs because the user that the Nginx worker process runs as does not have read permissions for the certificate files or their parent directories.

  1. Identify the Nginx user: Look for the user directive in your main nginx.conf file (such as user nginx;).

  2. Check permissions: Ensure that this user has read (r) permissions on the certificate and private key files, and execute (x) permissions on all parent directories leading to them.