Linux, Apache, MySQL, PHP (LAMP) for beginners...
Enough to get you started... (this was done in AWS).
- Launch a new EC2 instance from AWS' Red Hat 7 AMI (free tier)
- Log into it using "ec2-user"
- Elevate privilege
sudo su - - Do a fresh update
yum update - Add repositories
- REMI:
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm - EPEL
rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm - MySQL
rpm -Uvh https://repo.mysql.com/mysql80-community-release-el7.rpm - Installing Apache
- Yum install command
yum install httpd - Set it to start on boot:
systemctl enable httpd.service - Start it now:
systemctl start httpd.service - Default log location (access_log and error_log)
/var/log/httpd - Default configuration
/etc/httpd/conf/httpd.conf - Installing mysql
- Yum install command
yum install mysql-server - Set this to start on boot:
systemctl enable mysqld.service - Start it now
systemctl start mysqld.service - Get the mysql temporary password for root
grep "A temporary password" /var/log/mysqld.log | tail -nl - You should get something like this...
[Server] A temporary password is generated for root@localhost: V!cedo*iP0iW - Secure your mysql
mysql_secure_installation - Accept all secure measures. Don't forget your new password!
- Install php
- Do it from REMI repo (RedHat only comes with php 5.3)
yum --enablerepo=epel,remi-php73 install php - Install Modules of your choice (these are what I installed)
yum --enablerepo=remi-php73 install php-mysql php-xml php-xmlrpc php-soap php-gd php-fpm - Restart Apache for the php install to take effect
systemctl restart httpd.service - You should be able to browse to it now
- you can do it locally:
curl locahost - You can do it remotely
http://publicIP - If you don't see it from remote, try turning off IPTABLES
systemctl status iptables - Write your first HTML page
- Go to /var/www/html/
- Edit a new file
vi index.html - Paste the following
<html> <head> </head> <body> <p>Hello World</p> </body> </html>
- Write your first PHP page
- Still at /var/www/html/
- Edit a new file
vi index.php - Anything inside <?php and ?> will be interpreted as PHP code
- Paste the following
<html> <head> </head> <body> <?php print("Hello World"); phpinfo(); ?> </body> </html>
- Let's secure your site
- Install mod_ssl module
yum install mod_ssl - Get self-signed cert via this command(or look up how to purchase one or get a free one from cacert.org)
openssl req -newkey rsa:2048 -nodes -keyout /etc/ssl/private/myserver.key -x509 -days 365 -out /etc/ssl/private/myserver.crt - Go to /etc/httpd/conf.d
- Create a new file ssl.conf and paste the following into it
LoadModule ssl_module modules/mod_ssl.so Listen 443 <VirtualHost *:443> ServerName myserver SSLEngine on SSLCertificateFile "/etc/ssl/private/myserver.crt" SSLCertificateKeyFile "/etc/ssl/private/myserver.key" </VirtualHost>
- Restart httpd
systemctl restart httpd.service - Check log if you run into issue, you may have a syntax error
- Go to your browser and use https instead
- Bonus Round! Let's accept client certs. Go here for more info.
- Update the previous step's ssl.conf with this new
LoadModule ssl_module modules/mod_ssl.so Listen 443 <VirtualHost *:443> ServerName myserver SSLEngine on SSLCertificateFile "/etc/ssl/private/myserver.crt" SSLCertificateKeyFile "/etc/ssl/private/myserver.key"
SSLCACertificateFile "/etc/ssl/private/myserver.crt" ## Your choice here is required, optional, and optional_no_ca SSLVerifyClient optional_no_ca ## this is number of depths of CA to traverse, use 1 SSLVerifyDepth 1 ## this send the cert info to PHP SSLOptions +StdEnvVars +ExportCertData ## this will allow it to accept your own CA unknown to browser SSLCADNRequestPath /etc/ssl/private/ </VirtualHost>
- Restart httpd so that the new ssl.conf is accepted
- At this point, you need a cert loaded to your browser to test this
- You can use your company cert
- You can also use self-signed cert and loaded onto your browser (use openssl to self-sign a key pair then use "openssl pkcs12" command to put it together as PKCS12 so that you can import it into your browser)
- Now browse to your sample PHP page you created before and you should get prompted for your cert, give it and let's take a look at the Apache Environment variables
- Creating a table to hold visitor credential. Here's additional how-to mysql.
- Log into mysql
mysql -u root -p - Create a new database
mysql> CREATE DATABASE mylamp; - Select this database for use
mysql> USE mylamp; - Let's create our table
CREATE TABLE users ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, lastvisit_at DATETIME DEFAULT CURRENT_TIMESTAMP );
- Let's check it
mysql> SHOW TABLES; - You can also do this:
mysql> DESCRIBE users; - Now let's create a new user to access this table (I'm disabling password validation for this user). More info here.
SET GLOBAL validate_password.policy=LOW; CREATE USER 'mylampuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; GRANT ALL ON mylamp.* TO 'mylampuser'@'localhost' WITH GRANT OPTION;
- You can exit now
mysql> exit - Let's create some PHP files to write user information to the table. Here's additional info on how to do this.
- Create a new file, config.php (at /var/www/html)
vi config.php - Paste the following
<?php /* Database credentials. */ define('DB_SERVER', 'localhost'); define('DB_USERNAME', 'mylampuser'); define('DB_PASSWORD', 'password'); define('DB_NAME', 'mylamp'); /* Attempt to connect to MySQL database */ $link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); // Check connection if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } ?>
- Create a new file, login.php (also at /var/www/html)
vi login.php - Paste the following
<?php // Include config file session_start(); require_once "config.php"; if(isset($_SERVER['SSL_CLIENT_S_DN_Email'])){ $_SESSION['username'] = $_SERVER['SSL_CLIENT_S_DN_Email']; $username = $_SERVER['SSL_CLIENT_S_DN_Email']; $sql = "SELECT id FROM users WHERE username = ?"; if($stmt = mysqli_prepare($link, $sql)){ // Bind variables to the prepared statement as parameters mysqli_stmt_bind_param($stmt, "s", $username); // Attempt to execute the prepared statement if(mysqli_stmt_execute($stmt)){ /* store result */ mysqli_stmt_store_result($stmt); if(mysqli_stmt_num_rows($stmt) == 1){ //update user $sql = "UPDATE users SET lastvisit_at = now() where username = ?"; } else{ //add a new user $sql = "Insert into users (username) values (?)"; } if($stmt = mysqli_prepare($link, $sql)){ mysqli_stmt_bind_param($stmt, "s", $username); if(mysqli_stmt_execute($stmt)){ mysqli_stmt_store_result($stmt); mysqli_stmt_free_result($stmt); mysqli_stmt_close($stmt); } }else{ echo "Oops! Something went wrong. Please try again later."; } } else{ echo "Oops! Something went wrong. Please try again later."; } } }else{ $_SESSION['username'] = 'unknown'; } echo $_SESSION['username']; mysqli_close($link); ?>
- Also create users.php to view all the entries in the table
vi users.php - Paste the following (more info here)
<?php require_once "config.php"; $sql = "SELECT * from users"; if($stmt = mysqli_prepare($link, $sql)){ if(mysqli_stmt_execute($stmt)){ mysqli_stmt_store_result($stmt); printf("Number of rows: %d.<br>", mysqli_stmt_num_rows($stmt)); mysqli_stmt_bind_result($stmt, $id, $username, $created, $lastuse); while(mysqli_stmt_fetch($stmt)){ printf("%s -- %s -- %s -- %s. <br>",$id,$username,$created,$lastuse); } mysqli_stmt_free_result($stmt); mysqli_stmt_close($stmt); } }else{ echo "Oops! Something went wrong. Please try again later."; } /* close connection */ mysqli_close($link); ?>
- Browse to users.php, you'll see 0 entries
- In a new tab, open login.php, you should get success
- Now, go back to users.php tab, and refresh the page, you should see 1 entry with your information.
- For extra flexibility, you can include this in your other page to process the login action (index.php)
<html> <head> </head> <body> <?php include 'login.php'; print("Hello World"); ?> </body> </html>