It doesn’t take rocket science to set up and run a web server in the AWS cloud. Here is a down-to-earth, step-by-step primer for adventurous newbies.
Related: How to set up a mail server on AWS EC2 using open source software.
I. Allow your web server to be discoverable
Step 1. Reserve a domain name
Reserve a domain name with a registrar of your choice. AWS Route 53 is one of many options; in fact, any registrar will do. Feel free to shop around for the best deals. (Yes, it is possible to switch the registrar and keep the domain name.)
Step 2. Create a hosted zone
Create a hosted zone with a DNS service of your choice such as AWS Route 53. (Don’t bother looking for a freebie; with DNS services, you get what you pay for). See this post for more details: A quick guide to DNS configuration using AWS Route 53 (or any other DNS service).
Your DNS service provider will assign you between no less than two DNS servers. These are the so-called NS records for your domain that you will need in Step 3.
Step 3. Assign name servers to your domain
Enter the NS records from your hosted zone with the registrar of your domain as your NS servers of record (enter their host names without the dots).
Step 4. Provision an EC2 instance with the software stack of your choice
Fire up an EC2 instance and install the web server of your choice. Our recommended stack is the NGINX as the web server, MariaDB as the database server, and php-fpm from #remirepo (see: How to set up the LEMP stack: Linux, NGINX, MariaDB or MySQL, PHP).
II. Set up your web server for static content delivery
Step 5. Create the website root directory
Create a new website root directory in the web server document root for your domain www.domainname.tld (it’s good practice to name the directory just that). Now you can populate it with content.
Step 6. Create system users for NGINX and website owners
Create a Unix user without shell access and add it to the group nginx. To separate individual websites, create separate website owners and add them to the group NGINX.
For quick reference:
useradd -md /var/www/www.website.root1.tld -s /sbin/nologin websiteowner1 usermod -G nginx websiteowner1
Edit the NGINX configuration for each site, for example: www.domainname.tld. For additional flexibility in handling multiple domains, use symlinks to reference active configuration files as described in this post (search for sites-enabled and sites-available).
For quick reference:
[root@ip-16-0-0-40 sites-enabled]# ln -s /etc/nginx/sites-available/www.domainname.tld
Step 7. Upload your web documents and/or install a CMS of your choice
Install a content management system such as WordPress by downloading it directly to your instance, unzipping, and copying the files to the web server document directory. It is recommended to set up remote access via SFTP to the web server root directory using key pairs.
Step 8. Adjust file access permissions
Adjust file access permissions on the web server root directory.
For quick reference:
find /var/path/to/web/directory -type f -exec chmod 640 {} \; find /var/path/to/web/directory -type d -exec chmod 750 {} \;
Remember to also adjust SELinux permissions on the web server root directory (also on any newly created configuration files, and anywhere else if applicable).
At this point, you should be able to serve static content.
III. Set up your web server for web application delivery
Step 9. Configure your PHP interpreter
Configure a php-fpm pool for your website. Make sure the pool is running as the same Unix user that will own its web server document directory and its contents (you created those users in Step 7 above and are going to grant them file access permissions on the appropriate directories in Step 13 below).
To verify that the PHP interpreter is running correctly, enter:
systemctl status php70-php-fpm
Step 10. Set up connectivity between your web server and your application server/PHP interpreter
In order to facilitate communications between the web server and php-fpm you can use either Unix sockets or TCP/IP sockets (TCP/IP sockets allow your server to scale more efficiently but have somewhat higher performance requirements). In either case, make sure that SELinux allows access to the interface you chose; here is how to allow access via TCP/IP sockets in SELinux.
Here is an example configuration file for NGINX running a PHP application such as WordPress in a sub-directory and using TCP/IP sockets on the default port 9000 (please unlock with your social karma):
[sociallocker]
server { listen 80; server_name www.domainname.tld domainname.tld; # define the location of the web server document directory for this website root /var/www/www.domainname.tld; # define the order in which files will be served index index.php index.html index.htm; # for WordPress: include restrictions (please refer to the WordPress codex for details) include global/restrictions.conf; # when the web application sits in a subdirectory named blog: location /blog { # Empty; this is just here to avoid redirecting for this location, # though you might already have some config in a block like this. try_files $uri $uri/ /blog/index.php?q=$request_uri; } # redirecting traffic from the host name to the subdirectory blog location / { return 301 /blog/$1; try_files $uri $uri/ /index.php?$args; } # pass PHP scripts to a FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { try_files $uri =404; root /var/www/www.domainname.tld; fastcgi_pass 127.0.0.1:9000; # pass PHP scripts to a Unix socket instead of a TCP connection # fastcgi_pass unix:/var/run/php-fpm.sockets/www.domainname.tld.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } # for WordPress: include global configuration (please refer to the WordPress Codex for details) include global/wordpress.conf; }
[/sociallocker]
Step 11. Adjust the settings of your security management system
Adjust SELinux labels on newly created configuration files using:
[root@ip-16-0-0-40 sites-available]# chcon -R -v system_u:object_r:httpd_config_t:s0 www.domainname.tld
Then restart NGINX and php-fpm to apply configuration changes.
III. Set up a database
Step 12. Create a database
Create a database for your web application and a database user with limited permissions that is allowed access to it.
Quick reference:
[sociallocker]
mysql -u root -p CREATE USER 'DBuser'@'localhost'; select * from mysql.user; create database content_DB; GRANT ALL PRIVILEGES ON content_DB.* TO DBuser@localhost IDENTIFIED BY 'thisuserspassword';
As soon as you create a user account, you have to IMMEDIATELY grant all privileges to root: GRANT ALL PRIVILEGES ON *.* TO root@'::1' IDENTIFIED BY 'rootuserspassword' WITH GRANT OPTION; SET PASSWORD FOR 'root'@'::1' = PASSWORD('rootuserspassword');
SHOW GRANTS FOR 'root'@'localhost'; SHOW GRANTS FOR 'DBuser'@'localhost';
flush privileges;
[/sociallocker]
Step 13. Set up database connectivity in your CMS
To make sure that your CMS system knwos how to access the database, you need to configure it with the appropriate database access credentials. For WordPress, you simply enter the SQL connection parameters into the wp-config.php configuration file of your WordPress installation.
IV. Security hardening
Step 14. Adjust your AWS security group
Adjust the settings of the AWS Security Group that is assigned to your instance by opening ports for NGINX (typically port 80 for http and 443 for https in both HTTP/1.1 and HTTP/2)
Step 15. Complete the WordPress set-up
Complete the installation of WordPress by visiting the website in your web browser.
Follow the onscreen instructions in order to create a WordPress administrator. This user will sign in in step 15.
Step 16. Polish your WordPress to perfection
Sign in to WordPress with the user credentials of the WordPress administrator. Install themes, plug-ins and other extensions to your hear’s content. In some cases, you may need to perform uploads outside of WordPress; Windows users can deploy FileZilla for convenient SFTP transfer of files between the local computer and your EC2 instance.
Back-up your server instance.
Now is the time for some advanced security hardening of your web content.
Leave a Reply