I am in the process of reinstalling the OS on a machine that will be used to host a couple of applications for our business. The applications will be local only; access from external clients will be via VPN only.
The prior setup used a hosting control panel (Plesk) for most of the admin, and I was looking at using another similar piece of software for the reinstall - but I figured I should finally learn how it all works. I can do most of the things the software would do for me, but I am unclear on the symbiosis of it all. This is all an attempt to further distance myself from the land of Configuration Programmer/Programmer, if at all possible.
I can't find a full walkthrough anywhere for what I'm looking for, so I thought I'd put up this question, and if people can help me on the way I will edit this with the answers, and document my progress/pitfalls. Hopefully someday this will help someone down the line.
The details:
- CentOS 5.5 x86_64
- httpd: Apache/2.2.3
- MySQL: 5.0.77 (to be upgraded)
- PHP: 5.1 (to be upgraded)
The requirements:
- SECURITY!!
- Secure file transfer
- Secure client access (SSL Certs and CA)
- Secure data storage
- Secure connection to another local machine (MySQL)
- Virtualhosts/multiple subdomains
- Local email would be nice, but not critical
The Steps:
While going through the install, I checked the Server Components option thinking I was going to be using another Plesk-like admin. In hindsight, considering I've decided to try to go my own way, this probably wasn't the best idea.
Setup users, networking/IP address, etc. Yum update/upgrade.
To upgrade PHP and MySQL to the latest versions, I had to look to another repo outside CentOS. IUS looks great and I'm happy I found it!
Add IUS repository to our package manager
cd /tmp
wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/epel-release-1-1.ius.el5.noarch.rpm
rpm -Uvh epel-release-1-1.ius.el5.noarch.rpm
wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1-4.ius.el5.noarch.rpm
rpm -Uvh ius-release-1-4.ius.el5.noarch.rpm
yum list | grep -w \.ius\. # list all the packages in the IUS repository; use this to find PHP/MySQL version and libraries you want to install
Remove old version of PHP and install newer version from IUS
rpm -qa | grep php # to list all of the installed php packages we want to remove
yum shell # open an interactive yum shell
remove php-common php-mysql php-cli #remove installed PHP components
install php53 php53-mysql php53-cli php53-common #add packages you want
transaction solve #important!! checks for dependencies
transaction run #important!! does the actual installation of packages.
[control+d] #exit yum shell
php -v
PHP 5.3.2 (cli) (built: Apr 6 2010 18:13:45)
Upgrade MySQL from IUS repository
/etc/init.d/mysqld stop
rpm -qa | grep mysql # to see installed mysql packages
yum shell
remove mysql mysql-server #remove installed MySQL components
install mysql51 mysql51-server mysql51-devel
transaction solve #important!! checks for dependencies
transaction run #important!! does the actual installation of packages.
[control+d] #exit yum shell
service mysqld start
mysql -v
Server version: 5.1.42-ius Distributed by The IUS Community Project
Upgrade instructions courtesy of IUS wiki: http://wiki.iuscommunity.org/Doc/ClientUsageGuide.
scp
and sftp
access, without allowing ssh
logincd /tmp
wget http://dag.wieers.com/rpm/packages/rssh/rssh-2.3.2-1.2.el5.rf.x86_64.rpm
rpm -ivh rssh-2.3.2-1.2.el5.rf.x86_64.rpm
useradd -m -d /home/dev -s /usr/bin/rssh dev
passwd dev
Edit /etc/rssh.conf
to grant access to SFTP to rssh users.
vi /etc/rssh.conf
Uncomment or add:
allowscp
allowsftp
This allows me to connect to the machine via SFTP protocol in Transmit (my FTP program of choice; I'm sure it's similar with other FTP applications).
rssh instructions appropriated (with appreciation!) from http://www.cyberciti.biz/tips/linux-unix-restrict-shell-access-with-rssh.html.
ifconfig eth1:1 192.168.1.3 up #start up the virtual interface
cd /etc/sysconfig/network-scripts/
cp ifcfg-eth1 ifcfg-eth1:1 #copy default script and match name to our virtual interface
vi ifcfg-eth1:1 #modify eth1:1 script
#ifcfg-eth1:1 | modify so it looks like this:
DEVICE=eth1:1
IPADDR=192.168.1.3
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
NAME=eth1:1
Add more Virtual interfaces as needed by repeating. Because of the ONBOOT=yes
line in the ifcfg-eth1:1 file, this interface will be brought up when the system boots, or the network starts/restarts.
service network restart
Shutting down interface eth0: [ OK ]
Shutting down interface eth1: [ OK ]
Shutting down loopback interface: [ OK ]
Bringing up loopback interface: [ OK ]
Bringing up interface eth0: [ OK ]
Bringing up interface eth1: [ OK ]
ping 192.168.1.3
64 bytes from 192.168.1.3: icmp_seq=1 ttl=64 time=0.105 ms
In the rssh section above I added a user to use for SFTP. In this users' home directory, I created a folder called 'https'. This is where the documents for this site will live, so I need to add a virtualhost that will point to it. I will use the above virtual interface for this site (herein called dev.site.local).
vi /etc/http/conf/httpd.conf
Add the following to the end of httpd.conf:
<VirtualHost 192.168.1.3:80>
ServerAdmin [email protected]
DocumentRoot /home/dev/https
ServerName dev.site.local
ErrorLog /home/dev/logs/error_log
TransferLog /home/dev/logs/access_log
</VirtualHost>
I put a dummy index.html file in the https directory just to check everything out. I tried browsing to it, and was met with permission denied errors. The logs only gave an obscure reference to what was going on:
[Mon May 17 14:57:11 2010] [error] [client 192.168.1.100] (13)Permission denied: access to /index.html denied
I tried chmod 777 et. al., but to no avail. Turns out, I needed to chmod+x the https directory and its' parent directories.
chmod +x /home
chmod +x /home/dev
chmod +x /home/dev/https
This solved that problem.
I'm handling DNS via our local Windows Server 2003 box. However, the CentOS documentation for BIND can be found here: http://www.centos.org/docs/5/html/Deployment_Guide-en-US/ch-bind.html
To get SSL working, I changed the following in httpd.conf:
NameVirtualHost 192.168.1.3:443 #make sure this line is in httpd.conf
<VirtualHost 192.168.1.3:443> #change port to 443
ServerAdmin [email protected]
DocumentRoot /home/dev/https
ServerName dev.site.local
ErrorLog /home/dev/logs/error_log
TransferLog /home/dev/logs/access_log
</VirtualHost>
Unfortunately, I keep getting (Error code: ssl_error_rx_record_too_long) errors when trying to access a page with SSL. As JamesHannah gracefully pointed out below, I had not set up the locations of the certs in httpd.conf, and thusly was getting the page thrown at the broswer as the cert making the browser balk.
So first, I needed to set up a CA and make certificate files. I found a great (if old) walkthrough on the process here: http://www.debian-administration.org/articles/284.
Here are the relevant steps I took from that article:
mkdir /home/CA
cd /home/CA/
mkdir newcerts private
echo '01' > serial
touch index.txt #this and the above command are for the database that will keep track of certs
Create an openssl.cnf
file in the /home/CA/
dir and edit it per the walkthrough linked above. (For reference, my finished openssl.cnf file looked like this: http://pastebin.com/raw.php?i=hnZDij4T)
openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 3650 -config ./openssl.cnf #this creates the cacert.pem which gets distributed and imported to the browser(s)
Modified openssl.cnf
again per walkthrough instructions.
#generates certificate request, and key.pem which I renamed dev.key.pem.
openssl req -sha1 -new -nodes -out dev.req.pem -config ./openssl.cnf
Modified openssl.cnf
again per walkthrough instructions.
#create and sign certificate.
openssl ca -out dev.cert.pem -md sha1 -config ./openssl.cnf -infiles dev.req.pem
IMPORTANT!
Move the files and reference them from httpd.conf in the new location
cp dev.cert.pem /home/dev/certs/cert.pem
cp dev.key.pem /home/certs/key.pem
I updated httpd.conf to reflect the certs and turn SSLEngine on:
NameVirtualHost 192.168.1.3:443
<VirtualHost 192.168.1.3:443>
ServerAdmin [email protected]
DocumentRoot /home/dev/https
SSLEngine on
SSLCertificateFile /home/dev/certs/cert.pem
SSLCertificateKeyFile /home/dev/certs/key.pem
ServerName dev.site.local
ErrorLog /home/dev/logs/error_log
TransferLog /home/dev/logs/access_log
</VirtualHost>
Put the CA cert.pem in a web-accessible place, and downloaded/imported it into my browser. Now I can visit https://dev.site.local with no errors or warnings.
And this is where I'm at. I will keep editing this as I make progress. Any tips on how to configure SSL email, and/or configuring secure connection to another Box that will be the MySQL server would be appreciated.
This guide has a lot of answers about using SSL with Apache, tells you how to create a self-signed certificate, how to get a proper certificate from a recognized certificate authority (CA) and how to create your own, untrusted CA to create a full certificate. http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html
As for virtual hosts and SSL, each host will need its own IP address or a dirtier solution is to host them on different ports, than the standard
:443
due to the nature of SSL certificates, name-based virtual hosting does not get along with SSL; which is why you need another method to differentiate; differing ports/IPs.Setting up SSH is pretty easy, it should be running on your server, already. You will want to do a number of things to lock it down.
It can be added to your
/etc/ssh/sshd_config
to restrict remote root access, and remove password authentication, instead using public/private keypairs to log in.To create your SSH keypair, you can use
puttygen
in Windows; http://putty.very.rulez.org/download.html or you can create the keypair in a Linux environment like so:ssh-keygen -b 2048 -t RSA -f my_keypair
. This will create amy_keypair
file and amy_keypair.pub
file (only named for this example, I might suggest naming for your username or leaving off-f
, and letting it generate~/.ssh/id_rsa
).Securely transfer
my_keypair
to your workstation, for future SSH access, this is the private key, you should not share it with anyone. Then, on the server, create$HOME/.ssh
if it does not already exist,mkdir ~/.ssh
, then copy the public key (my_keypair.pub
) to~/.ssh/
, if you already haveauthorized_keys
in~/.ssh
because you've done this for other things, you can docat my_keypair.pub >> authorized_keys
to append your public key, orcp my_keypair.pub authorized_keys
if it doesn't exist.Now run
chmod 700 ~/.ssh
andchmod 644 ~/.ssh/my_keypair.pub ~/.ssh/authorized_keys
to set permissions. You can keep a copy ofmy_keypair
in~/.ssh/
for use when connecting to other hosts, but you should dochmod 600 ~/.ssh/my_keypair
to make sure no one else can access it.You will want to add a normal user account for yourself, and add yourself to a group other than
users
, likeadmins
in my example.You will probably also want to add your user or group to
/etc/sudoers
to enablesudo
usage, if you haven't already. This is accomplished with the commandvisudo
which is the only way you should edit this file.visudo
runs error and syntax checking on your configuration before writing it out, preventing loss ofsudo
usage.added to
/etc/sudoers
will allowusername
to runsudo yum install blah
and will prompt you for your own password. This is handy in the event you have other administrators or temporary administrators, you don't need to share the root password.The problem with your SSL config is that you've not actually enabled SSL, you'd need the Apache directives for that:
Without this you'll get those record too long errors, it's because instead of the SSL headers your browser was expecting, it's getting instead just the unencrypted web page in a big chunk.
MySQL from the original package supports SSL. To check your MySQL build, run
You should find something like
have_ssl yes
. Set up optionsssl-ca
,ssl-key
andssl-cert
.Create user accounts with SSL requirements: