Yusuf Ibrahim
Yusuf Ibrahim

Reputation: 1619

Spring Boot and Single Instance AWS Beanstalk SSL Setup Error

I have an issue related SSL and HTTPS (Certbot and LetsEncrypt on Corretto 11 running on 64bit Amazon Linux 2/3.1.0) setup on Single Instance AWS Beanstalk. This environment is for staging environment before later I'll setup real Environtment using Load balancer.

I followed the following tutorial https://medium.com/@phil_mldtsv/configuring-your-aws-elastic-beanstalk-single-instance-spring-boot-app-for-https-using-lets-9750c03a8860

and here is my error:

2020/08/23 07:01:16 [error] 6360#0: *166 connect() failed (111: Connection refused) while connecting to upstream, client: 78.151.174.205, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "54.255.115.127:80"
2020/08/23 08:29:20 [warn] 6360#0: *170 using uninitialized "year" variable while logging request, client: 45.141.84.124, server: , request: "��/*����Cookie: mstshash=Administr"
2020/08/23 08:29:20 [warn] 6360#0: *170 using uninitialized "month" variable while logging request, client: 45.141.84.124, server: , request: "��/*����Cookie: mstshash=Administr"
2020/08/23 08:29:20 [warn] 6360#0: *170 using uninitialized "day" variable while logging request, client: 45.141.84.124, server: , request: "��/*����Cookie: mstshash=Administr"
2020/08/23 08:29:20 [warn] 6360#0: *170 using uninitialized "hour" variable while logging request, client: 45.141.84.124, server: , request: "��/*����Cookie: mstshash=Administr"
2020/08/23 09:11:40 [error] 6360#0: *171 connect() failed (111: Connection refused) while connecting to upstream, client: 193.138.154.68, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "54.255.115.127:80"
2020/08/23 09:36:08 [error] 6360#0: *173 connect() failed (111: Connection refused) while connecting to upstream, client: 195.54.160.21, server: , request: "GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1", upstream: "http://127.0.0.1:5000/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php", host: "54.255.115.127:80"
2020/08/23 09:43:16 [error] 6360#0: *175 connect() failed (111: Connection refused) while connecting to upstream, client: 180.251.244.69, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "54.255.115.127:80"
2020/08/23 10:50:06 [error] 6360#0: *179 connect() failed (111: Connection refused) while connecting to upstream, client: 5.76.67.42, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "54.255.115.127:80"

And here is my .config file

Resources:
  sslSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
      IpProtocol: tcp
      ToPort: 443
      FromPort: 443
      CidrIp: 0.0.0.0/0

files:
  /tmp/redirect.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      return 301 https://$host$request_uri;

  /tmp/java_app.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      server {
        listen 443 ssl;

        error_page  497 https://$host$request_uri;

        ssl_certificate /etc/letsencrypt/live/ebcert/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ebcert/privkey.pem;

        ssl_session_timeout 5m;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_prefer_server_ciphers on;

        if ($ssl_protocol = "") {
          rewrite ^ https://$host$request_uri? permanent;
        }

        location / {
          proxy_pass http://127.0.0.1:5000;
          proxy_set_header Connection "";
          proxy_http_version 1.1;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
        }
      }

  /opt/elasticbeanstalk/hooks/configdeploy/post/mv_config_deploy.sh:
    mode: "000644"
    owner: root
    group: root
    content: |
      #!/bin/bash -xe
      mv /tmp/java_app.conf /var/elasticbeanstalk/staging/nginx/conf.d/
      mv /tmp/redirect.conf /var/elasticbeanstalk/staging/nginx/conf.d/elasticbeanstalk/

container_commands:
  01_install_certbot:
    command: "wget https://dl.eff.org/certbot-auto;chmod a+x certbot-auto"
  02_stop_nginx:
    command: "sudo service nginx stop"
  03_getcert:
    command: "sudo ./certbot-auto certonly --debug --non-interactive --standalone --email ${certemail} --agree-tos -d ${certdomain} --keep-until-expiring"
  04_link:
    command: "ln -sf /etc/letsencrypt/live/${certdomain} /etc/letsencrypt/live/ebcert"
  05_mvconfig:
    command: "sudo sh /opt/elasticbeanstalk/hooks/configdeploy/post/mv_config_deploy.sh;sudo rm -f /opt/elasticbeanstalk/hooks/configdeploy/post/mv_config_deploy.sh"
  06_removeconfig:
    command: "sudo service nginx start"

Here is my security Group Config

enter image description here

From inside the instance enter image description here

Any body can tell what is wrong with my config? Thanks in advance.

Upvotes: 5

Views: 1080

Answers (2)

Drashti Dobariya
Drashti Dobariya

Reputation: 3006

All the current AWS documentation as of now (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-java.html) are for corretto java 8 Linux 1 platform. Also, the .config file that you have mentioned will also work with that old platform.

For Corretto Java 11 Linux 2 platform, since it is a different platform, you would require different config files.

Now, you need to add .ebextensions folder and also another folder named .platform

In the .ebextensions folder, you will need to add two .config files - one for installing certbot and generating certificates and another to create a cron job to renew the certificate. The second step is optional, however, since Letsencrypt certificate expires in 3 months, it's crucial to renew the certificate so that https keeps on working.

In the .platform, create this folder structure nginx/conf.d. Inside conf.d folder, create a file with the name https.conf.

Now, if you want to redirect from HTTP to HTTPS, then you need one more configuration file inside conf.d/elasticbeanstalk folder with name 00_application.conf. Please note that the name 00_application.conf is very important, as there is already a file with that name inside the Nginx folder and we will be replacing that file content with the new one to redirect traffic from HTTP to HTTPS. If you provide another name then it will not work.

Project Structure:

root
  - .ebextensions
      - https-instance.config
      - renew-ssl.config
  - .platform
      - nginx
          - conf.d
              - elasticbeanstalk
                 - 00_application.conf
              - https.conf
  - Procfile
  - Application Jar

https-instance.config

packages:
  rpm:
    epel: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

commands:
  01_install_certbot_packages:
    command: sudo yum -y install certbot-nginx
  02_generate_ssl:
    command: sudo certbot certonly --nginx -d ${enter_your_domain_name} --non-interactive --email ${enter_your_email_here}@gmail.com  --agree-tos

renew-ssl.config (This command renews certificate every monday at 3:30 AM)

files:
  /etc/cron.d/renewssl:
    content: |
      30 3 * * 1 root /usr/bin/certbot renew --quiet # quit not valid

00_application.conf

location / {
     set $redirect 0;
     if ($http_x_forwarded_proto != "https") {
       set $redirect 1;
     }
     if ($http_user_agent ~* "ELB-HealthChecker") {
       set $redirect 0;
     }
     if ($redirect = 1) {
       return 301 https://$host$request_uri;
     }

     proxy_pass          http://127.0.0.1:5000;
     proxy_http_version  1.1;

     proxy_set_header    Connection          $connection_upgrade;
     proxy_set_header    Upgrade             $http_upgrade;
     proxy_set_header    Host                $host;
     proxy_set_header    X-Real-IP           $remote_addr;
     proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
}

https.conf

# HTTPS server

server {
    listen       443;
    server_name  localhost;

    ssl                  on;
    ssl_certificate      /etc/letsencrypt/live/${enter_your_domain_name}/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/${enter_your_domain_name}/privkey.pem;

    ssl_session_timeout  5m;

    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;

    location / {
        proxy_pass  http://localhost:5000;
        proxy_set_header   Connection "";
        proxy_http_version 1.1;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto https;
    }
}

Procfile

web: java -jar ${application_jar_name}.jar

Finally, in the end, zip all the conf folders along with the jar and upload the zipped folder to aws.

PS: I have assumed the default port as 5000 here. If you are changing it via env variables, then you will need to change the port value in config files.

Upvotes: 2

Yusuf Ibrahim
Yusuf Ibrahim

Reputation: 1619

The Certbot is error due to compatibility issue with the latest version of Amazon LInux 2/4.10. There is nothing to do, you need to set up your own manual load balancer and set up the ssl certificate there.

Upvotes: 1

Related Questions