This is an old revision of the document!
Linux Setup
Installation
- Download CD images (ISO files) from http://fedora.redhat.com
- Burn the ISO images into CDROMs.
- Install Fedora.
- Partition hard disk as necessary.
- Install all the required software packages.
Adding a New Hard Drive
- Create partition using
fdisk /dev/<partitionname>
. Eg:% fdisk /dev/hdb1
- Format new partition using
mkfs -t ext3 /dev/<partitionname>
. Eg:% mkfs -t ext3 /dev/hdb1
- Check new partition file system integrity using
fsck -f -y /dev/<partitionname>
. Eg:% fsck -f -y /dev/hdb1
- Mount the new partition. First create a folder where to mount (Eg:
/data
), then mount. Eg:% mkdir /data % mount /dev/hdb1 /data
- Add entry to file
/etc/fstab
for automatic mounting. Eg:/dev/hdb1 /data ext3 defaults 1 1
Linux Configuration
Global Aliases
Setup some basic aliases for users to have a simpler navigation at the command line. Add the following commands to /etc/profile.d/sysaliases.sh
:
alias l='ls -l' # display file list in long format alias ll='ls -la' # display file list in long format and include all files (hidden as well) alias cls=clear # clear the screen
Alternatively, you can add these commands at the end of file /etc/bashrc
.
User Information
- Use
chfn
to change user finger information (full name, office, phone, etc). - Use
chsn
to change user login shell. - Use
finger
usernameto view the current finger information. For example:
$ finger jdoe Login: jdoe Name: John Doe Directory: /home/jdoe Shell: /bin/bash Office: Software Development, 211 On since Mon Aug 14 09:29 (EDT) on pts/0 from 192.168.0.3 No mail. No Plan.
Apache
''htaccess'' Authentication
Create .htaccess
file
- NOTE 1:
< protectedfolder >
is where the actual folder name is going to be - NOTE 2: The password file path in
AuthUserFile
should ideally be outside of the webserver root.
AuthType Basic AuthName "Only for Authenticated Users. Please contact your sales representative for a username and password" AuthUserFile /data/www/html/<protectedfolder>/.htpasswd <Limit GET> Require valid-user </Limit>
Create a password file and add a user:
% cd /data/www/html/<protectedfolder> % htpasswd -c .htpasswd <username>
Only add a username and password (no creation of password file):
% cd /data/www/html/<protectedfolder> % htpasswd .htpasswd <username>
Troubleshooting ''htaccess''
Source: Apache Tutorial: htaccess Files 1)
When you put configuration directives in a .htaccess
file, and you don't get the desired effect, there are a number of things that may be going wrong.
Most commonly, the problem is that AllowOverride
is not set such that your configuration directives are being honored. Make sure that you don't have a AllowOverride None
in effect for the file scope in question. A good test for this is to put garbage in your .htaccess
file and reload. If a server error is not generated, then you almost certainly have AllowOverride None
in effect.
If, on the other hand, you are getting server errors when trying to access documents, check your Apache error log. It will likely tell you that the directive used in your .htaccess file is not permitted. Alternately, it may tell you that you had a syntax error, which you will then need to fix.
Look for this statement (and comment it out) in file /etc/httpd/conf/httpd.conf
(or /etc/apache2/sites-available/default
in Ubuntu). It should be:
#AllowOverride None
Default Character Encoding
Some pages will display characters incorrectly. The character encoding might need to be changed from the default UTF-8
to the following (file /etc/httpd/conf/httpd.conf
):
AddDefaultCharset ISO-8859-1
PHP Input Filters
For installations with PHP 5.1 or higher, this step is not necessary since the filters are installed by default. For other installations, setup PHP filters using the following commands:
$ wget http://pecl.php.net/filter/get $ tar xzf filter-0.11.0 $ phpize $ ./configure $ make $ make install
Then edit /etc/php.ini
and add:
extension=filter.so
Restart the web server.
In case there is an error such as error: ext/pcre/php_pcre.h: No such file or directory
, install file php_pcre.h
in /usr/local/include/php/ext/pcre/
(or /usr/include/php5/ext/pcre
):
/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2006 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Andrei Zmievski <andrei@php.net> | +----------------------------------------------------------------------+ */ /* $Id: php_pcre.h,v 1.44 2006/01/01 13:09:52 sniper Exp $ */ #ifndef PHP_PCRE_H #define PHP_PCRE_H #if HAVE_PCRE || HAVE_BUNDLED_PCRE #if HAVE_BUNDLED_PCRE #include "pcrelib/pcre.h" #else #include "pcre.h" #endif #if HAVE_LOCALE_H #include <locale.h> #endif PHP_FUNCTION(preg_match); PHP_FUNCTION(preg_match_all); PHP_FUNCTION(preg_replace); PHP_FUNCTION(preg_replace_callback); PHP_FUNCTION(preg_split); PHP_FUNCTION(preg_quote); PHP_FUNCTION(preg_grep); PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC); PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC); PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC); extern zend_module_entry pcre_module_entry; #define pcre_module_ptr &pcre_module_entry typedef struct { pcre *re; pcre_extra *extra; int preg_options; #if HAVE_SETLOCALE char *locale; unsigned const char *tables; #endif int compile_options; int refcount; } pcre_cache_entry; PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len, pcre_extra **extra, int *preg_options, int *compile_options TSRMLS_DC); ZEND_BEGIN_MODULE_GLOBALS(pcre) HashTable pcre_cache; ZEND_END_MODULE_GLOBALS(pcre) #ifdef ZTS # define PCRE_G(v) TSRMG(pcre_globals_id, zend_pcre_globals *, v) #else # define PCRE_G(v) (pcre_globals.v) #endif #else #define pcre_module_ptr NULL #endif /* HAVE_PCRE || HAVE_BUNDLED_PCRE */ #define phpext_pcre_ptr pcre_module_ptr #endif /* PHP_PCRE_H */
SSL Certificate
For Apache, we need to get the following cert components:
- Package with cert and private key (encrypted) in PKCS#12 or PFX format (extension
.pfx
or.p12
):acme-cert-key-pair.pfx
- Organization's cert (usually PEM format) (extension
.crt
or.pem
):acme-cert-pem.crt
- Organization's decrypted private key (extension
.key
):acme-decrypted.key
- Cert Authority chain or bundle (extension
.crt
):gd_bundle.crt
Get PFX file from Certificate Authority (CA), then extract cert and private key (encrypted and decrypted). Eg. for organization Acme:
#!/bin/bash # # Export the private key file from the pfx file echo "### Export the private key file from the pfx file" openssl pkcs12 -in acme-cert-key-pair.pfx -nocerts -out acme-encrypted.key # Remove the passphrase from the private key echo echo "### Remove the passphrase from the private key" openssl rsa -in acme-encrypted.key -out acme-decrypted.key # Export the certificate file from the pfx file echo echo "### Export the certificate file from the pfx file" openssl pkcs12 -in acme-cert-key-pair.pfx -clcerts -nokeys -out acme-cert-pem.crt
NOTE: The PKCS#12 or PFX format is a binary format for storing the server certificate, any intermediate certificates, and the private key in one encryptable file. PFX files usually have extensions such as .pfx and .p12. PFX files are typically used on Windows machines to import and export certificates and private keys.
When converting a PFX file to PEM format, OpenSSL will put all the certificates and the private key into a single file. You will need to open the file in a text editor and copy each certificate and private key (including the BEGIN/END statments) to its own individual text file and save them as certificate.cer, CACert.cer, and privateKey.key respectively.
The PEM format is the most common format that Certificate Authorities issue certificates in. PEM certificates usually have extentions such as .pem, .crt, .cer, and .key. They are Base64 encoded ASCII files and contain “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” statements. Server certificates, intermediate certificates, and private keys can all be put into the PEM format.
Apache and other similar servers use PEM format certificates. Several PEM certificates, and even the private key, can be included in one file, one below the other, but most platforms, such as Apache, expect the certificates and private key to be in separate files. (Source: https://www.sslshopper.com/ssl-converter.html)
Edit /etc/apache2/sites-available/default-ssl
to include:
# A self-signed (snakeoil) certificate can be created by installing # the ssl-cert package. See # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. # #--- Self-signed Certificate & Key --- ##SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem ##SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key #--- CA-signed Certificate & Key --- # Note: When Private Key is decrypted, it requires no password when restarting Apache SSLCertificateFile /etc/ssl/certs/acme-cert-pem.crt SSLCertificateKeyFile /etc/ssl/private/acme-decrypted.key ##SSLCertificateKeyFile /etc/ssl/private/acme-encrypted.key # Server Certificate Chain: # Point SSLCertificateChainFile at a file containing the # concatenation of PEM encoded CA certificates which form the # certificate chain for the server certificate. Alternatively # the referenced file can be the same as SSLCertificateFile # when the CA certificates are directly appended to the server # certificate for convinience. #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt SSLCertificateChainFile /etc/apache2/ssl.crt/ca-godaddy-bundle.crt
Restart Apache:
% /etc/init.d/apache2 restart
Verification
- Check apache error logs. Eg:
% tail -f /var/log/apache2/error.log
- Check the website using
https
in the URL. - Check the padlock icon on the URL in the browser. Get information from certificate.
- Visit SSL Labs and submit site to analyze security.
References
Obtaining Cert from Cert Authority (CA)
When getting a cert, a CA will request to submit a CSR file with the multiple domains that will be using the cert. This is how to create the CSR file using the SubjectAltName
method in OpenSSL, assuming we need it to certify domains acme.com www.acme.com secure.acme.com:
Create an OpenSSL custom config file /etc/ssl/mycerts/openssl.cnf
:
[ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name req_extensions = req_ext # The extentions to add to the self signed cert [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Florida localityName = Locality Name (eg, city) localityName_default = Longwood organizationName = Organization Name (eg, company) organizationName_default = Acme, Inc. commonName = Common Name (eg, YOUR name) commonName_default = www.acme.com commonName_max = 64 [ req_ext ] subjectAltName = @alt_names [alt_names] DNS.1 = acme.com DNS.2 = secure.acme.com
Generate the private key file
$ openssl genrsa -out acme.key 2048
Generate the CSR file
$ openssl req -new -newkey rsa:2048 -nodes -keyout acme.key -out acme.csr -config openssl.cnf
Verify CSR file
$ openssl req -text -noout -in acme.csr
Once you are happy with the settings in that file, you can submit it to the CA to generate the certificate for you.
See also:
SELinux
Turning on/off enforcing at boot time 2):
You can specify the SELinux mode using the configuration file /etc/sysconfig/selinux
.
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= type of policy in use. Possible values are: # targeted - Only targeted network daemons are protected. # strict - Full SELinux protection. SELINUXTYPE=targeted
Setting the value to enforcing is the same as adding enforcing=1
to your command line when booting the kernel to turn enforcing on, while setting the value to permissive is the same as adding enforcing=0
to turn enforcing off. Note that the command line kernel parameter overrides the configuration file.
However, setting the value to disabled is not the same as the selinux=0
kernel boot parameter. Rather than fully disabling SELinux in the kernel, the disabled setting instead turns enforcing off and skips loading a policy.
Samba
Running
Register the Samba service to run at server boot time:
$ /sbin/chkconfig --level 35 smb on
Run the Samba service:
$ /sbin/service smb start
Add samba users. For example:
$ cd /etc/samba $ smbpasswd -a jdoe
NOTE: Make sure the samba user matches a Linux user, otherwise it will not create the samba user. If you do not wish to give the user shell access in Linux, just set the shell to /sbin/nologin
.
Testing
Test by connecting a client machine to the Samba server.
Linux
$ smbclient -L //server1 -d 3
Windows
C:\> net view \\server1 C:\> net use \\server1\data Enter the user name for 'server1': jdoe Enter the password for server1: ****
To disconnect from the share:
C:\> net use \\server1\data /delete
Troubleshooting
If after providing username and password there is no successful connection, and the error log in /var/log/samba/
machinename.log
shows
[2006/08/14 14:01:54, 0] smbd/service.c:make_connection_snum(911) ' ''ShareName'' ' does not exist or permission denied when connecting to [''ShareName''] Error was Permission denied
then you must configure SELinux to allow Windows XP client machines to connect correctly to those shares. Perform the following:
Configuring SELinux - Sharing User Home Directories
Source: Nazin Blog 3)
If you only share user home directories in Samba, then simply configure SELinux to allow that. There are two steps:
- Tell SELinux to allow the Samba daemon to access the smbpasswd and secrets.tdb files. Set the context of the smbpasswd and secrets.tdb files (this is a one-time action):
$ chcon -t samba_secrets_t /etc/samba/smbpasswd $ chcon -t samba_secrets_t /etc/samba/secrets.tdb
- Tell SELinux that it can share home directories. Place this line in the
booleans.local
file (usually at/etc/selinux/targeted/booleans.local
): samba_enable_home_dirs=1
This solution works perfectly, but only when sharing just user home directories. When sharing other paths, this solution is incomplete. You would need to disable SELinux for Samba.
Disabling SELinux, but Only for Samba!
Source: Nazin Blog 4)
Although there might be other ways to configure SELinux to allow Samba to share other paths, a quick solution is to simply disable SELinux for the Samba daemon only.
Perform the following commands once:
$ setsebool -P smbd_disable_trans 1 $ /sbin/service smb restart
The setsebool
command, with the -P option, will actually write this entry into the booleans.local
file for you, to make it permanent.
MySQL
Start the mysql service:
$ /sbin/service mysqld start
Register the mysql service to start up at boot time:
$ /sbin/chkconfig --level 35 mysqld on
Create a password for root user:
$ /usr/bin/mysqladmin -u root password 'new-password' $ /usr/bin/mysqladmin -u root -h server1.mydomain.com password 'new-password'
VNC Server
To connect to Linux's desktop remotely, use VNC Server on the Linux machine, and VNC Viewer on the client machine (Windows workstation).
On the Linux server, connect (ssh, telnet, etc.) with the desired user, then run the VNC Server:
$ vncserver
- Give it a password to access.
- Write down the display number:
server1.example.com:1
On the client machine, you have a choice on how to connect:
- Use the browser to access
http://server1.example.com:5801/
using the password. Note: the number 1 means the display connection number, so if you connected as display 7, the port should be 5807. - Use the VNC Client software. For example:
C:\Apps\VNC\> vncviewer.exe
Configure VNC to Load Automatically
Edit the file /etc/sysconfig/vncserver
to include all the users and their respective display settings. For example, we want the vncserver to boot automatically for users mayr and joel with displays 2 and 3 respectively, we would do the following:
# # /etc/sysconfig/vncserver # #The VNCSERVERS variable is a list of display:user pairs. # separated by spaces, eg: VNCSERVERS="1:joe 2:jill" # # Uncomment the line below to start a VNC server on display :1 # as my 'myusername' (adjust this to your own). You will also # need to set a VNC password; run 'man vncpasswd' to see how # to do that. # # DO NOT RUN THIS SERVICE if your local area network is # untrusted! For a secure way of using VNC, see # <URL:http://www.uk.research.att.com/vnc/sshvnc.html>. VNCSERVERS="1:jsmith 2:jdoe"
Configure VNC to run GNOME/KDE as desktop
Startup settings: edit the file ~/.vnc/xstartup
#!/bin/sh # Linux VNC session startup script unset SESSION_MANAGER vncconfig -iconic & xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & xterm -geometry 80x50+510+10 -ls -title "$VNCDESKTOP Desktop" & xterm -geometry 80x24+10+350 -ls -title "$VNCDESKTOP Desktop" -bg black -fg white & exec /etc/X11/xinit/xinitrc
Configure VNC to run TWM (Tom's Window Manager) as desktop
Startup settings: edit the file ~/.vnc/xstartup
#!/bin/sh # Uncomment the following two lines for normal desktop: # unset SESSION_MANAGER # exec /etc/X11/xinit/xinitrc [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources xsetroot -solid grey vncconfig -iconic & xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & xterm -geometry 80x50+510+10 -ls -title "$VNCDESKTOP Desktop" & xterm -geometry 80x24+10+350 -ls -title "$VNCDESKTOP Desktop" -bg black -fg white & twm &
Stop a VNC session
Stop a VNC session (assuming it is in display :1) :
$ vncserver -kill :1
GUI Desktops
You can switch between the following desktops:
- enlightenment
- fluxbox
- fvwm
- gnome
- icewm
- kde
- toplevel
- twm
- wmaker
- xfce
Use the switchdesk
command. For example:
$ switchdesk kde
Firewall
Enable the the iptables
firewall, and use the /etc/rc.d/arno-iptables-firewall
to tighten security. First, edit the file /etc/arno-iptables-firewall.conf
:
# Put in the following variables which ports or IP protocols you want to leave # open to the whole world. # ----------------------------------------------------------------------------- OPEN_TCP="22 80" OPEN_UDP="22 80" OPEN_IP="" OPEN_ICMP=0
Run the script /etc/rc.d/arno-iptables-firewall
to start it:
$ cd /etc/rc.d/ $ ./arno-firewall-script.sh restart
Uncomplicated Firewall (UFW) in Ubuntu
- Refer to UFW Documentation and IPTables How To.
- Enable
ufw
:% ufw enable
- Add rules:
% ufw default deny % ufw allow to any port 80 # http % ufw allow to any port 443 # https % ufw allow from 192.168.0.0/24 to any port 22 # ssh % ufw allow from 192.168.0.0/24 to any port 25 # smtp % ufw allow from 192.168.0.0/24 to any port 123 # ntp % ufw allow from 192.168.0.0/24 to any port 143 # imap % ufw allow from 192.168.0.0/24 to 192.168.0.149 port 465 # smtp over SSL % ufw allow from 192.168.0.0/24 to any port 53 # dns % ufw allow from 192.168.0.0/24 to any port 67 # dhcp server % ufw allow from 192.168.0.0/24 to any port 68 # dhcp client % ufw allow proto udp from 192.168.0.0/24 to 192.168.0.149 port 137 # samba NetBIOS Name Service % ufw allow proto udp from 192.168.0.0/24 to 192.168.0.149 port 138 # samba NetBIOS Datagram Service % ufw allow from 192.168.0.0/24 to any port 139 # samba NetBIOS Session Service % ufw allow from 192.168.0.0/24 to any port 445 # samba SMB file sharing % ufw allow from 192.168.0.0/24 to 192.168.0.31 port 3690 # Subversion server using ip 192.168.0.31
- Delete rules:
% ufw delete allow to any port 80 # delete http rule
MediaWiki
Installation
- Download software from http://www.mediawiki.org
- Unzip files to target location (for example,
/var/www/html/wiki
)
$ tar xzvf mediawiki-x.x.x.tar.gz
- Create MySQL database and user:
mysql> create database wikidb; mysql> grant create, select, insert, update, delete, lock tables on wikidb.* to wiki@localhost identified by 'password'; mysql> flush privileges;
- Point the browser to the site and follow installation instructions. For example: http://www.yourdomain.com/wiki
- For more detailed installation instructions, visit [http://meta.wikimedia.org/wiki/Help:Installation MediaWiki Installation Help]
Configuration
Disable certain users from editing pages, and enabling others. Add the following lines to MediaWiki/LocalSettings.php
:
# Disable anonymous and regular users from editing pages $wgGroupPermissions['*']['edit'] = false; $wgGroupPermissions['user']['edit'] = false; # Enable 'swdev' group members to edit pages. # Add new groups here, just like 'swdev'. $wgGroupPermissions['swdev']['edit'] = true;
To change which groups a user belongs to, login as Admin
and visit Special:Specialpages and click the link to 'User Rights Management' on the very bottom of the list which will bring them to Special:Userrights and follow the on-screen instructions.
Troubleshooting
Getting a blank screen after posting an edit or uploading an image file
- Check the limit of settings
upload_max_filesize
andpost_max_size
in file/etc/php.ini
. - Under Fedora and Apache, this problem happens with large files. Fix it by increasing the memory limits in
MediaWiki/LocalSettings.php
:
ini_set( 'memory_limit', '20M' ); # You might need to increase the limit
Sendmail
Mail Spool
Directory permissions for /var/spool/mail
should be drwxrwxr-x
for group mail
(in case it is not working). Otherwise, it will have trouble sending mail.
Configuration
Verify version of Sendmail:
$ sendmail -d0.1 -bt < /dev/null
Default Sendmail Settings for Receiving Mail
The default configuration for Sendmail does not allow for the receiving of mail except from yourself (localhost). To receive mail, perform the following operations:
- Backup the files
/etc/mail/sendmail.mc
and/etc/mail/sendmail.cf
- Edit the file
/etc/mail/sendmail.mc
and change/comment the lineDAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
to display:
dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
- Sendmail will then use the default which allows it to receive mail from other systems.
Mail Relay
Setup mechanism for mail relay. Choose one of the following (be careful with the quotes ` ' ):
FEATURE(`relay_entire_domain')dnl <-- domain names must be added to /etc/mail/access FEATURE(`relay_hosts_only')dnl <-- hosts names (FQDN) must be added to /etc/mail/access
Run this command to regenerate sendmail.cf:
$ m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
Edit files /etc/mail/local-host-names
. It contains all of the alternate host names of the server. (i.e. domain-name.com) Sendmail will not accept mail for a domain unless it is permitted to do so by the contents of this file.
#--- /etc/mail/local-host-names --- example.com mail.example.com 10.10.10.2
Create /etc/mail/access
and /etc/mail/relay-domains
to add domains and handle mail for those domains. Otherwise, the anti-spam configuration will only honor local mail and refuse any other.
#--- /etc/mail/access --- localhost.localdomain RELAY localhost RELAY 127.0.0.1 RELAY example.com RELAY 192.168. RELAY
#--- /etc/mail/relay-domains --- example.com RELAY_FROM mail.example.com RELAY_FROM pc01.example.com RELAY_FROM dsl01.cableco.com RELAY_FROM 10.10.10.2 RELAY_FROM 192.168.0. RELAY_FROM
Regenerate hash tables by typing:
$ makemap hash /etc/mail/access < /etc/mail/access $ makemap hash /etc/mail/relay-domains < /etc/mail/relay-domains
Run and Test Sendmail
Restart the sendmail service:
$ /sbin/service sendmail restart
Test sendmail with verbose mode:
$ date | sendmail -v jdoe@hotmail.com
Blocking Spam and Unwanted Relaying
Edit the file /etc/mail/access
to include:
#--- /etc/mail/access --- from:nobody REJECT from:apache REJECT from:apache@localhost REJECT apache@ REJECT apache@localhost REJECT
Remove unsafe copies of /cgi-bin/formmail.pl
. It allows external users to send mail as nobody@localhost or apache@locahost. Do a security audit on users' cgi programs, and you might find one with a vulnerablity. If you must use one, install one you can trust in a common cgi-bin, and instruct users on how to use it.
Mail Aliases
- Directory permission for
/var/spool/mail
should bedrwxrwxr-x
for group mail. Otherwise, it will have trouble sending mail. - Global aliases (file
/etc/aliases
): Various error messages in the system will normally be issued as internal email. To ensure that these will actually be read, one should create an/etc/aliases
. An example that should cover most eventualities is:
# # /etc/aliases # format: alias: name # postmaster: root ftp: root news: root usenet: root faxmaster: root fax: root webmaster: root mailer.daemon: root support: superadmin, jsmith acctng: jdoe, jsmith
- Recreate aliases database. Remember to issue the command
newaliases
every time you change/etc/aliases
.
$ newaliases
Mail Routing
In the DNS database entry for example.com (file /etc/named/example.com.hosts
), include the proper MX record. This is a slightly different example compared to the DNS file shown above (see DNS Configuration):
; ; Zone file for example.com ; ; domain = example.com ; host = server1.example.com ; e-mail = root@example.com ; @ IN SOA example.com. root.example.com. ( 20010016 ; Serial 8H ; Refresh 2H ; Retry 1W ; Expire 1D) ; Minimum TTL TXT "Sample DNS Server" NS example.com. ; internet address of name server MX 10 example.com. ; primary mail exchanger ; localhost A 127.0.0.1 router A 200.35.85.89 ns A 200.35.85.90 www A 200.35.85.90 mail A 200.35.85.90 pop A 200.35.85.90 server1 A 192.168.1.2 ftp A 192.168.1.2
Add the domain name to the /etc/hosts
file in the line where the mail host is found. This is done because of mail looping occurs when the DNS zone (see above zone definition /etc/named/example.com.hosts
) has the same mail hosts as the hosts being defined. Here server1
, mail
, and example.com
are the same, so looping will occur and delivery of messages will not occur. Eg: server1.example.com
is the mail server in this case so:
# # /etc/hosts # # For loopbacking. 127.0.0.1 localhost 200.35.85.90 www.example.com www mail.example.com mail example.com 192.168.1.2 server1.example.com server1 example.com # End of hosts.
InterNetNews (INN) Server
Configuration
Configure the server. Edit the following files: /etc/news/expire.ctl
# Keep local newsgroup 3 months (server1.example.com). server1.*:A:3:90:90
/etc/news/nnrp.access
## nnrp.access - access file for on-campus NNTP sites ## Format: ## <host>:<perm>:<user>:<pass>:<groups> ## Connecting host must be found in this file; the last match found is ## used, so put defaults first. ## <host> Wildcard name or IP address ## <perm> R to read; P to post ## <user> Username for authentication before posting ## <pass> Password, for same reason ## <groups> Newsgroup patterns that can be read or not read ## To disable posting put a space in the <user> and <pass> fields, since ## there is no way for client to enter one. ## ## Default is no access, no way to authentication, and no groups. *:: -no- : -no- :!* ## Foo, Incorporated, hosts have no password, can read anything. *:Read Post:::spinnaker* localhost:Read Post:::* server1.example.com:Read Post:::*
Run service:
$ /sbin/service innd start $ /sbin/chkconfig --level 35 innd on
Security (Giving Access)
Disable SELinux protection:
$ setsebool -P innd_disable_trans 1 $ /sbin/service innd restart
Edit the permissions file /etc/news/readers.conf
to enable local machines to read/post:
# This auth group matches all connections from example.com or machines in # the example.com domain and gives them the identity <local>@example.com. # Instead of using wildmat patterns to match machine names, you could also # put a wildmat pattern matching IP addresses or an IP range specified # using CIDR notation (like 10.10.10.0/24) here. auth "local" { hosts: "*.example.com, example.com, 192.168.0.0/24" default: "<local>@example.com" } . . . # Now for the access groups. All of our access groups should have users: # parameters so there are no access groups that match connections without # an identity (such as are generated by the "abusers" entry above). # First, the default case of local users, who get to read and post to # everything. access "local" { users: "<local>@example.com" newsgroups: "*" }
Creating Local Newsgroup
To create a local news group, perform the following steps:
- Make sure service
innd
is running. - Add an entry for the new local group in
/etc/news/expire.ctl
, (in the site directory, thenmake install
). - Add a descriptive entry to newsgroups. Lock the
/var/lib/news/newsgroups
file, usingshlock
, and append the newsgroup description to the file. The following example seems to function:$ shlock -f /var/lib/news/LOCK.newsgroups -p $$ && echo "examplesite.class.bskt201<tab>Introductory Basket Weaving" >> /var/lib/news/newsgroups && rm /var/lib/news/LOCK.newsgroups
- Finally, the group can be added with the command:
$ /usr/lib/news/bin/ctlinnd newgroup examplesite.dept.news.group m "John Doe (Mod)"
- Add entries to
/etc/news/newsfeeds
to restrict the local groups to your organization:ME:!local.*:: out.going.site:*,!local.*:Tf,Wnm:
Please consider, that local
is a very common name for local groups, so if a user crossposts to local.test
and misc.test
the article will show up in all local.test
over the world. So please choose a 'better' name.
Further Reading
Backup Critical Data and Configuration
Create a daily cron task to backup some important files to a directory (for example: /data/backup
). This script should be created as /etc/cron.daily/backup.sh
:
#!/bin/bash ## script: /etc/cron.daily/backup.sh ## ## removes old backup file rm -rf /data/backup/* ## backup the following directories: tar -czvf /data/backup/mail-backup.tar.gz /var/spool/mail tar -czvf /data/backup/home-backup.tar.gz /home tar -czvf /data/backup/website-backup.tar.gz /var/www/html tar -czvf /data/backup/mysql-data-backup.tar.gz /var/lib/mysql tar -czvf /data/backup/etc-dir.tar.gz /etc ## send reminder to sysadmin to pull the tarball from the server. mail root -s "Get the backup tarball off the server"
sudo Configuration
Source: Quick HOWTO: Linux Users and Sudo 5)
Use sudo when several administrators maintain a system. This allows access to the right people without giving away full root access, and losing track of what changes were done by whom.
Obtaining root Privileges
$ sudo more /etc/sudoers
Becoming root Using a Regular User
The su command allows a regular user to become the system's root user if they know the root password. A user with sudo rights to use the su command can become root, but they only need to know their own password, not that of root as seen here.
jdoe@example.com:~$ sudo su - Password: root@example.com:~#
Some systems administrators will use sudo to grant root privileges to their own personal user account without the need to provide a password.
Creating sudo users
Use this special text editor that is used to edit the /etc/sudoers configuration file:
$ visudo
Creating /etc/sudoers file
File format:
usernames/group servername = (usernames command can be run as) command
Guidelines:
There are some general guidelines when editing this file:
- Groups are the same as user groups and are differentiated from regular users by a % at the beginning. The Linux user group “users” would be represented by
%users
. - You can have multiple usernames per line separated by commas.
- Multiple commands also can be separated by commas. Spaces are considered part of the command.
- The keyword
ALL
can mean all usernames, groups, commands and servers. - If you run out of space on a line, you can end it with a back slash (\) and continue on the next line.
- sudo assumes that the sudoers file will be used network wide, and therefore offers the option to specify the names of servers which will be using it in the servername position. In most cases, the file is used by only one server and the keyword
ALL
suffices for the server name. - The
NOPASSWD
keyword provides access without prompting for your password.
Simple /etc/sudoers Examples
This section presents some simple examples of how to do many commonly required tasks using the sudo utility.
Granting All Access to Specific Users
You can grant users jdoe
and jsmith
full access to all privileged commands, with this sudoers entry.
jdoe, jsmith ALL=(ALL) ALL
This is generally not a good idea because this allows jdoe and jsmith to use the su command to grant themselves permanent root privileges thereby bypassing the command logging features of sudo. The example on using aliases in the sudoers file shows how to eliminate this problem.
Granting Access To Specific Users To Specific Files
This entry allows user peter
and all the members of the group operator
to gain access to all the program files in the /sbin
and /usr/sbin directories
, plus the privilege of running the command /usr/local/apps/check.pl
. Notice how the trailing slash (/) is required to specify a directory location:
peter, %operator ALL= /sbin/, /usr/sbin, /usr/local/apps/check.pl
Notice also that the lack of any username entries within parenthesis () after the = sign prevents the users from running the commands automatically masquerading as another user. This is explained further in the next example.
Granting Access to Specific Files as Another User
The sudo -u
entry allows allows you to execute a command as if you were another user, but first you have to be granted this privilege in the sudoers file.
This feature can be convenient for programmers who sometimes need to kill processes related to projects they are working on. For example, programmer peter
is on the team developing a financial package that runs a program called monthend
as user accounts
. From time to time the application fails, requiring “peter” to stop it with the /bin/kill
, /usr/bin/kill
or /usr/bin/pkill
commands but only as user “accounts”. The sudoers entry would look like this:
peter ALL=(accounts) /bin/kill, /usr/bin/kill /usr/bin/pkill
User peter
is allowed to stop the monthend
process with this command:
[peter@bigboy peter]# sudo -u accounts pkill monthend
Granting Access Without Needing Passwords
This example allows all users in the group operator
to execute all the commands in the /sbin
directory without the need for entering a password. This has the added advantage of being more convenient to the user:
%operator ALL= NOPASSWD: /sbin/
Using Aliases in the sudoers File
Sometimes you'll need to assign random groupings of users from various departments very similar sets of privileges. The sudoers file allows users to be grouped according to function with the group and then being assigned a nickname or alias which is used throughout the rest of the file. Groupings of commands can also be assigned aliases too.
In the next example, users peter
, jdoe
and jsmith
and all the users in the operator
group are made part of the user alias ADMINS
. All the command shell programs are then assigned to the command alias SHELLS
. Users ADMINS
are then denied the option of running any SHELLS commands and su
:
Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, \ /usr/bin/ksh, /usr/local/bin/tcsh, \ /usr/bin/rsh, /usr/local/bin/zsh User_Alias ADMINS = peter, bob, bunny, %operator ADMINS ALL = !/usr/bin/su, !SHELLS
This attempts to ensure that users don't permanently su to become root, or enter command shells that bypass sudo's command logging. It doesn't prevent them from copying the files to other locations to be run. The advantage of this is that it helps to create an audit trail, but the restrictions can be enforced only as part of the company's overall security policy.
Using syslog To Track All sudo Commands
All sudo commands are logged in the log file /var/log/messages
which can be very helpful in determining how user error may have contributed to a problem. All the sudo log entries have the word sudo in them, so you can easily get a thread of commands used by using the grep
command to selectively filter the output accordingly.
Here is sample output from a user jdoe
failing to enter their correct sudo password when issuing a command, immediately followed by the successful execution of the command /bin/more sudoers
.
[root@example.com/tmp]# grep sudo /var/log/messages Nov 18 22:50:30 example.com sudo(pam_unix)[26812]: authentication failure; logname=jdoe uid=0 euid=0 tty=pts/0 ruser= rhost= user=jdoe Nov 18 22:51:25 example.com sudo: jdoe : TTY=pts/0 ; PWD=/etc ; USER=root ; COMMAND=/bin/more sudoers [root@example.com/tmp]#
rsync Server to Backup/Mirror Hosts
Server Setup
Setup the following files on the server.
- Configuration file. File /etc/rsyncd.conf:
# File /etc/rsyncd.conf motd file = /etc/rsyncd.motd log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock [webfiles] path = /var/www/t/test comment = Audina RSync Server (temp webserver) uid = www-data gid = www-data read only = yes list = yes auth users = root,jdoe,webmirror secrets file = /etc/rsyncd.scrt hosts allow = 192.168.0.0/24
- The Message of the Day. File
/etc/rsyncd.motd
:Welcome to Audina's RSync server (temp webserver)
- Secrets or password file. File
/etc/rsyncd.scrt
:# File /etc/rsyncd.scrt # rsyncd password file # username:password (not same username/password as system) root:interestingpass jdoe:asyncpass webmirror:mywebsyncpass
- Start
rsync
as a daemon (service):% rsync --daemon --config=/etc/rsyncd.conf
Client
- Setup and run a client script to launch a connection to the server:
#!/bin/bash # File /root/getwebfiles.sh # Example: Get files from server 192.168.0.149 (source) to local directory /data/mirror/webserver/www (destination) #rsync --verbose --progress --stats --compress --rsh=/usr/bin/ssh \ # --recursive --times --perms --links --delete \ # --exclude "*bak" --exclude "*~" \ # 192.168.0.149::webfiles /var/www/mirror rsync --archive --verbose --progress --stats --rsh=/usr/bin/ssh --recursive --times --perms --links --delete 192.168.0.149::webfiles /data/mirror/webserver/www
- Connect to server, type
ssh
password, then when connected, typersync
password if it prompts for it (when usingauth users
directive in server side/etc/rsyncd.conf
file).
rsynce References
Spyware/Malware Detection
- Use IP address check sites:
- StopForumSpam: Eg: check like this
http://www.stopforumspam.com/api?ip=216.24.206.59&f=json"
or with script
spamcheck.php
:<?php $url = "http://www.stopforumspam.com/api?ip=".$_GET["ip"]."&f=json"; $data = file_get_contents($url); $results = json_decode($data, true); print $results["ip"]["frequency"]; //print_r($results); ?>
Call it by:
http://www.example.com/spamcheck.php?ip=68.65.109.27
- BotScout.com: Eg:
http://www.botscout.com/ipcheck.htm?ip=216.24.206.59
- Check out what is monopolizing the CPU time (Refer to CPU Utilization):
% ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10 OR % ps -eo pcpu,pid,user,args | sort -r -k1 | less
NTP Server
ntpdate
- Create a file
/etc/cron.daily/ntpdate
containing:ntpdate ntp.ubuntu.com
- The file /etc/cron.daily/ntpdate must also be executable.
% sudo chmod 755 /etc/cron.daily/ntpdate
- Update the time on the server:
% ntpdate -u ntp.ubuntu.com pool.ntp.org
ntpd
- Setup
ntpd
:% sudo apt-get install ntp
- Edit
/etc/ntp.conf
to include servers to connect:server ntp.ubuntu.com server pool.ntp.org
- Add firewarll rule (
iptables
) to allow incoming queries from clients trying to synchronize to this server:% iptables -A INPUT -p udp --dport 123 -j ACCEPT % iptables -A OUTPUT -p udp --sport 123 -j ACCEPT
DNS Server (BIND9)
Master
- Install DNS server BIND9:
% apt-get install bind9 bind9-doc bind9utils
Slave
- Add range to be allowed in transfer zones. Edit file
/etc/bind/named.conf.options
:options { directory "/etc/bind"; // If there is a firewall between you and nameservers you want // to talk to, you may need to fix the firewall to allow multiple // ports to talk. See http://www.kb.cert.org/vuls/id/800113 // If your ISP provided one or more IP addresses for stable // nameservers, you probably want to use them as forwarders. // Uncomment the following block, and insert the addresses replacing // the all-0's placeholder. // forwarders { // 0.0.0.0; // }; # add a range you allow to transfer zones allow-transfer { localhost; 192.168.0.0/24; }; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { none; }; };
- Add slave zone to file
/etc/bind/named.conf.default-zones
:// slave zone. Check transfer with: % dig @192.168.0.104 acme.com. axfr zone "acme.com" { type slave; masters { 192.168.0.104; 192.168.0.101; }; file "/etc/bind/slaves/acme.com"; };
- Create directory
/etc/bind/slaves
:% mkdir /etc/bind/slaves % chmod g+w /etc/bind/slaves % chown -R bind:bind /etc/bind/slaves
- Enable UFW firewall:
% ufw enable % ufw allow to any port 80 # http % ufw allow from 192.168.0.0/24 to any port 53 # dns % ufw allow from 192.168.0.0/24 to any port 22 # ssh % ufw allow from 192.168.0.0/24 to any port 67 # dhcp server % ufw allow from 192.168.0.0/24 to any port 68 # dhcp client % ufw status
- Add permissions:
- AppArmor: Edit file
/etc/apparmor.d/usr.sbin.named
and add:/etc/bind/slaves/** rw, /etc/bind/slaves/ rw,
- Enable zone transfer on master server. In Windows server: DNS > <ServerName> > Forward Lookup Zones > <domainname>, and select properties (right-click on domain name). Select 'Zone Transfers' tab, and 'Allow zone transfer' > 'Only to the following servers' > <IP address of slave dns server> (eg: 192.168.0.104). Repeat these steps with the 'Notify' button in the same screen.
- Restart BIND9:
% /etc/init.d/bind9 restart
- Check slave zone transfer (assuming master server is 192.168.0.104):
% dig @192.168.0.2 acme.com. axfr
Fixing Ethernet Card not Detected on Ubuntu Server
When moving hard drives to new hardware, it might happen that network cards are not being detected, thus losing network access. To fix this:
- Edit file
/etc/udev/rules.d/70-persistent-net.rules
- Comment out all network cards defined there
- Reboot server
Sample /etc/udev/rules.d/70-persistent-net.rules
file:
# This file was automatically generated by the /lib/udev/write_net_rules # program, run by the persistent-net-generator.rules rules file. # # You can modify it, as long as you keep each rule on a single # line, and change only the value of the NAME= key. # PCI device 0x8086:/sys/devices/pci0000:00/0000:00:1e.0/0000:02:08.0 (e100) SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:07:e9:3c:34:1f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0" # PCI device 0x8086:/sys/devices/pci0000:00/0000:00:03.0/0000:02:01.0 (e1000) SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:07:e9:3c:34:1f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
Security
Cleaning Hacked Server
Run these tools to find injected code in PHP files, then edit the files to remove offending code (NOTE: injection code might not be obvious…it sits at the end of a long line after many spaces, typically the first php line), or simply delete those files (if no useful code belongs to your site):
$ cd /var/www $ find . -name "*.php" -exec grep -H "eval(" {} \;
Hacked scripts tend to have injected code that looks like this:
eval($p38d[$GLOBALS['y110d20'][21]]);
Look for odd and generic filenames, such as
info.php sql.php dir.php files.php start.php plugin0.php error.php htaccess
Also, search all files for a condition:
$ egrep -Rl 'function.*for.*strlen.*isset' /var/www $ egrep -Rl '\$GLOBALS.*\\x' /var/www $ egrep -Rl 'isset.*eval' /var/www $ egrep -Rl 'PHPMailer' /var/www $ egrep -Rl 'encodeURIComponent' /var/www $ egrep -Rl 'se_referrer' /var/www $ egrep -Rl 'base64_decode' /var/www $ find /var/www -newermt "yyyy-mm-dd"
Search all PHP files for a condition:
$ find /home/*/public_html/ -type f -name "*php" -exec egrep -l '\$GLOBALS.*\\x|function.*for.*strlen.*isset' "{}" \; $ find /var/www -type f -name "*php" -exec egrep -l 'se-referrer' "{}" \; $ find /var/www -type f -name "*php" -exec egrep -l 'base64_decode' "{}" \; $ find /var/www -type f -name "*php" -exec egrep -l '<iframe' "{}" \;
Sometimes, there are files tagged as .suspected
by the malware, in the hope that you will restore them without finding the malicious code embedded in them. To find files already tagged as .suspected
, use this command:
$ cd /var/www $ find . -name "*.php.suspected"
Check mail queue (sendmail
or postfix
) to make sure we are not spamming:
$ cd /var/spool/mqueue $ ls -la $ cd /var/spool/mqueue-client $ ls -la
Disable sendmail
if necessary until the server has been cleaned. Try one of these:
$ /etc/init.d/sendmail stop $ service sendmail stop
For a WordPress site, check database records for fishy code:
SELECT * FROM wp_posts WHERE post_content LIKE '%<iframe%' UNION SELECT * FROM wp_posts WHERE post_content LIKE '%<noscript%' UNION SELECT * FROM wp_posts WHERE post_content LIKE '%display:%' SELECT * FROM `wp_options` WHERE `option_name` LIKE '%srb_%' DELETE FROM `wp_options` WHERE `option_name` LIKE '%srb_%' DELETE FROM wp_options WHERE option_name LIKE '_transient_%' OR option_name LIKE 'displayed_galleries%'
In WordPress, query for unauthorized admin accounts:
SELECT u.ID, u.user_login FROM wp_usermeta m, wp_users u WHERE m.meta_key = 'wp_user_level' AND m.meta_value = 10 AND m.user_id = u.ID /* Delete unauthorized user with user_id = 312 */ DELETE FROM wp_usermeta WHERE user_id = 312 DELETE FROM wp_users WHERE ID = 312
Check the syslog to see if emails are being sent that are not supposed to:
$ tail -f /var/log/mail.log
Force any login to use HTTPS. Add a redirect for login in .htaccess
file:
RewriteCond %{HTTPS} off RewriteRule ^login$ https://www.acme.com/login [R=301,L]
Check for clean site, visiting this site:
Follow these other instructions to clean a hacked site:
References: