Installing and setting up OpenResty in Ubuntu
published on
In an effort to experiment with different web servers I decided to give OpenResty a try. OpenResty enhances NGinx by including a number of NGinx modules along with other things such as Lua and a number of Lua libraries.
This server can be used just like NGinx can along with the same configuration files but can also be used as a web app server as it includes the necessary lua modules for this.
Installing OpenResty on Ubuntu
When I was looking for instructions to install OpenResty on Ubuntu I found a number of different places offering ways of installing it. However, even using them I had to tweak, adapt and update instructions in order to get a working copy of OpenResty installed.
I have therefore documented this here for anyone who is interested.
You may also already have a working NGinx configuration file and server blocks that you choose to use. If not I have put together some here. However, it is worth mentioning that you should try and work out what each part does and only include it in your version if you want or need it.
Getting started
sudo apt-get -y install wget gnupg ca-certificateswget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
If you are using an x86/x64 system you should run the following commandecho "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
If you are using a system with an arm architecture then run the following command insteadecho "deb http://openresty.org/package/arm64/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
To install OpenRestysudo apt updatesudo apt install openresty openresty-resty openresty-restydoc openresty-opm openresty-zlib openresty-pcre luarocks
OpenResty should automatically start but just in case it doesn't
sudo systemctl start openrestysudo systemctl enable openresty
Install a firewall
sudo apt install ufwsudo ufw default deny incomingsudo ufw default allow outgoingsudo ufw logging lowsudo ufw allow 80sudo ufw allow 443sudo ufw enable
Install certbot for your free LetsEncrypt certificates
sudo apt-get install snapdsudo snap install core; sudo snap refresh coresudo snap install --classic certbotsudo ln -s /snap/bin/certbot /usr/bin/certbot
Initial configuration
You will want to set up a new directory for the logs to be written to and a new directory for all your site configuration files.
sudo mkdir /var/log/openrestysudo mkdir /usr/local/openresty/nginx/sites
Set up nginx.conf
Now it is time to create the nginx.conf file. I remove the existing one and replace it with one of my own.
sudo mv /usr/local/openresty/nginx/conf/nginx.{conf,original}sudo nano /usr/local/openresty/nginx/conf/nginx.conf
My nginx.conf version looks like this
user www-data;worker_processes auto;pid /usr/local/openresty/nginx/logs/nginx.pid;events { worker_connections 1024;
use epoll;
epoll_events 512; use epoll;}http { server_tokens off; include mime.types; default_type application/octet-stream; charset utf-8; charset_types text/css text/plain text/vnd.wap.wml text/javascript text/markdown text/calendar text/x-component text/vcard text/cache-manifest text/vtt application/json application/manifest+json; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/openresty/access.log combined; error_log /var/log/openresty/error.log warn; client_body_buffer_size 16K; client_header_buffer_size 1m; client_max_body_size 8m; large_client_header_buffers 4 8k; sendfile on; tcp_nopush on; tcp_nodelay on; gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 5; gzip_buffers 16 8k; gzip_min_length 256; gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/vnd.ms-fontobject application/wasm application/x-web-app-manifest+json application/xhtml+xml application/xml font/eot font/otf font/ttf image/bmp image/svg+xml text/cache-manifest text/calendar text/css text/javascript text/markdown text/plain text/xml text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; gzip_disable "MSIE [1-6]\."; reset_timedout_connection on; keepalive_timeout 20s; keepalive_requests 30; client_header_timeout 10; client_body_timeout 10; send_timeout 10s;
directio 4m; directio_alignment 512; open_file_cache max=1000 inactive=30s; open_file_cache_valid 30s; open_file_cache_min_uses 4; open_file_cache_errors on; # Limits limit_req_log_level warn; limit_req_zone $binary_remote_addr zone=reqlimit:10m rate=10r/m; limit_conn_zone $binary_remote_addr zone=connlimit:100m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on;include ../sites/*;}
You will notice the include ../sites/*; line at the end. This is how we will include any other sites you wish to serve on this machine but keep each of their configuration in seperate files.
Set up an initial server block for SSL certificate purposes
All server block configuration should be saved in /usr/local/openresty/nginx/sites/. I tend to name each file after the domain name I am using for the site. For example, if I was going to serve this site in OpenResty / NGinx I would call the configuration file philipstone.net.conf.
Add the following configuration to your file:
server { listen 80 default_server; listen [::]:80 default_server; root /usr/local/openresty/nginx/html/[domain]; # Add index.php if you are using PHP. index index.html index.htm;
server_name [domain] www.[domain]; # When we try to access this site... location / { try_files $uri $uri/ =404; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/openresty/nginx/html; }}
Now you have saved your server block configuration you need to create the directory you specified in the root directive above (e.g. root /usr/local/openresty/nginx/html/example.com;) and set the necessary permissions so that the server can read your files.
sudo mkdir /usr/local/openresty/nginx/html/[domain]sudo chown -R www-data: /usr/local/openresty/nginx/html/[domain]sudo chmod -R 750 /usr/local/openresty/nginx/html/[domain]/
Finally, reload the server to enable your new configuration
sudo systemctl reload openresty
Getting your SSL certificate
You will want to make sure your site has a working SSL certificate. If it doesn't it could affect your site's SEO score. To get a certificate for your site type
sudo certbot certonly --webroot -w /usr/local/openresty/nginx/html/[domain] -d [domain] -d www.[domain]
Lastly, test the certificate renewal will work.
certbot renew --dry-run
Update your site server block
Now that you have a SSL certificate it is time to replace your existing server block with one that will be more useful to you. I have included my sample server block file below. Please remember to alter it to suit your own requirements.
Some things you need to make note of are
- The
listen [::]:80(or 443) directives are only of any use to you if your server has an ipv6 address. Likewiselisten 80(or 443) directives are only of any use if you have an ipv4 address. Obviously you must have at least one of these. - I have used
example.comandwww.example.comas a server name here. This must be changed to your own domain name. - There is a redirect set up to always visit the
https://www.version of the site. If this isn't what you want then remove thewww.on thereturn 301 https://www.$server_name$request_uri;line. - The
content-security-policyand similar headers will need adapting to meet your own needs. - Find the caching section, near the end, and update it to reflect the settings that you prefer.
- The SSL certificate file paths will need to be updated with the ones you were given when running certbot.
server { listen 80; listen [::]:80 ipv6only=on; server_name example.com www.example.com; # Allow access to the ACME Challenge for Let's Encrypt <- <3 location ~ /\.well-known\/acme-challenge { allow all; } return 301 https://www.$server_name$request_uri;}server { listen 443 ssl http2; listen [::]:443 ipv6only=on ssl http2; server_name example.com www.example.com; root /usr/local/openresty/nginx/html/example.com; # Add index.php if you are using PHP. index index.html index.htm; charset utf-8; source_charset utf-8; ssl_certificate /path/to/signed_cert_plus_intermediates; ssl_certificate_key /path/to/private_key; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_stapling on; ssl_stapling_verify on; # When we try to access this site... location / { try_files $uri $uri/ =404; } # Httproxy vulnerability proxy_set_header Proxy ""; # Request headers for overwriting proxy_set_header X-Original-URL ""; proxy_set_header X-Rewrite-URL ""; proxy_set_header X-Rewrite-URL ""; proxy_set_header X-Host ""; proxy_set_header X-Forwarded-Server ""; proxy_set_header X-HTTP-Host-Override ""; proxy_set_header Forwarded ""; # Prevent Information leaks proxy_hide_header X-Powered-By; proxy_hide_header Server; proxy_hide_header X-AspNetMvc-Version; proxy_hide_header X-AspNet-Version; # http://blog.portswigger.net/2017/07/cracking-lens-targeting-https-hidden.html proxy_set_header clientIPAddress ""; proxy_set_header x-forwarded-for ""; proxy_set_header client-ip ""; proxy_set_header forwarded ""; proxy_set_header from ""; proxy_set_header referer ""; proxy_set_header x-client-ip ""; proxy_set_header x-originating-ip ""; proxy_set_header x-wap-profile ""; # http security headers add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY; add_header Pragma no-cache; add_header Cache-Control no-store; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy origin-when-cross-origin; add_header X-Permitted-Cross-Domain-Policies none; # Add Security cookie flags proxy_cookie_path ~(.*) "$1; SameSite=strict; secure; httponly"; # nonce!!, upgrade-insecure-requests!! add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'self'; base-uri 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' 'nonce-JjECqn6A' http: https:; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: http:; media-src 'none'; frame-src 'self'; font-src 'self'; connect-src 'self' wss:;"; #add_header Strict-Transport-Security "max-age=31536000; includeSubDomains;" always; # add_header Allow "GET, POST, HEAD"; ## Only allow these request methods ## ## Do not accept DELETE, SEARCH and other methods ## if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } # Allow access to the ACME Challenge for Let's Encrypt <- <3 location ~ /\.well-known\/acme-challenge { allow all; } # Deny all attempts to access hidden files # such as .htaccess, .htpasswd, .DS_Store (Mac), .git, .etc... location ~ /\. { deny all; } # caching - please check values location ~* .(ttf|mp3|mp4|webm|ogg|jpg|jpeg|png|gif|ico)$ { expires 1M; } location ~* .(css|js)$ { expires 1w; } error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 420 422 423 424 426 428 429 431 444 449 450 451 500 501 502 503 504 505 506 507 508 509 510 511 /error.html; location /error.html { internal; } limit_conn connlimit 1000; # Simultaneous Connections}
and finally restart the server to see your changes take effect
sudo systemctl reload openresty
Finally
Everything should now be installed and working perfectly. Your first site should also be online (which you can check by visiting your domain in a browser). If you can't access your site for some reason then make sure the permissions are set correctly by running the following command again
sudo chmod -R 750 /usr/local/openresty/nginx/html/[domain]/
In you would like to learn more about OpenResty, including looking through some of their video tutorials, visit https://openresty.org/en/.
