CentOS v7.0 Xen VM Image
Notes on manually creating a minimal CentOS 7 VM image.
/etc/fstab
Change the '/etc/fstab' to use labels (rather than uuids)
LABEL=/ / ext4 defaults 1 1 LABEL=swap swap swap defaults 0 0
Change the kernel boot parameters to also use a label based root (i.e. 'root=LABEL=/')
Packages
Delete unused packages:
# yum erase 'iwl*firmware' 'libertas*firmware' 'alsa*firmware' iprutils
Add useful diagnostic utilities:
# yum install man mlocate wget screen mtr bind-utils net-tools unzip psmisc yum-cron logwatch
admin user
Add an administration user that can sudo without a password. Add an account
- with a long random unknown password
- a member of the 'wheel' group
# adduser -G wheel --password `openssl rand -hex 32` -c "Greg" greg
Add the users ssh public key(s)
# su greg -c "umask 022 ; mkdir -p ~/.ssh ; vi ~/.ssh/authorized_keys"
Configure sudo to allow members of the wheel group to run commands without a password. Run 'visudo':
%wheel ALL=(ALL) NOPASSWD: ALL
ssh
protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key PermitRootLogin no AuthorizedKeysFile .ssh/authorized_keys PasswordAuthentication no ChallengeResponseAuthentication no UsePrivilegeSeparation sandbox KeepAlive no ClientAliveInterval 15 ClientAliveCountMax 9 SyslogFacility AUTHPRIV Subsystem sftp /usr/libexec/openssh/sftp-server
Restart sshd
# systemctl restart sshd.service
Network Manager
This image is intented for servers/appliances with simple static network requirements. Disable Network Manager & avahi.
# systemctl stop NetworkManager.service # systemctl disable NetworkManager.service # systemctl stop avahi-daemon.service # systemctl disable avahi-daemon.service
Tuned
Change the 'tuned' profile to virtual-guest:
# tuned-adm profile virtual-guest
Residual: Given a static tuned profile is selected, determine if it best to shut down the tuned daemon as it may consume more resources than it saves.
Network
Manually confiure /etc/resolv. Note that only the first three nameserver get used. Use IPv6 ULA/RFC-1918 addresses which should be less likely to be renumbered.
domain lucidsolutions.co.nz search lucidsolutions.co.nz nameserver fd0c:898b:471c:2::5 nameserver fd0c:898b:471c:c::2 nameserver 10.20.2.5 nameserver 10.20.12.2
/etc/sysconfig/network-scripts/ifcfg-eth0 (Note: the router is configured with an IPv6 address of fe80::1/64 on all network segments)
DEVICE=eth0 ONBOOT=yes NM_CONTROLLED=no TYPE=Ethernet BOOTPROTO=static # IPv4 IPADDR=10.20.x.2 GATEWAY=10.20.x.1 NETWORK=10.20.x.0 BROADCAST=10.20.x.255 NETMASK=255.255.255.0 NOZEROCONF=yes MTU=9000 # IPv6 IPV6ADDR=2001:4428:225:x::2/64 IPV6ADDR_SECONDARIES=fd0c:898b:471c:x::2/64 IPV6_DEFAULTGW=fe80::1%eth0 IPV6_AUTOCONF=no IPV6_MTU=9000
Postfix
Postfix is installed as part of the base minimal configuration. Change the configuration in '/etc/postfix/main.cf':Settings | Description |
---|---|
myorigin = $mydomain |
Mail from the virtual machine comes from user@lucidsiolutions.co.nz |
relayhost = $mydomain | All mail goes via the local SMTP smarthost. VM's won't be configured to sign mail or be listed in the SPF record. |
Proxy
Configure static proxy support through the environment. Applications can also use WPAD.
cat >> /etc/profile.d/proxy.sh <<EOF export http_proxy=http://proxy.lucidsolutions.co.nz:3128/ export https_proxy=http://proxy.lucidsolutions.co.nz:3128/ export ftp_proxy=http://proxy.lucidsolutions.co.nz:3128/ export no_proxy="127.0.0.1, localhost, 10.20.*, fd0c:898b:471c:*" EOF
In theory pam_env should load this file, but it doesn't:
cat >> /etc/environment <<EOF http_proxy=http://proxy.lucidsolutions.co.nz:3128/ https_proxy=http://proxy.lucidsolutions.co.nz:3128/ ftp_proxy=http://proxy.lucidsolutions.co.nz:3128/ no_proxy=127.0.0.1, localhost, 10.20.*, fd0c:898b:471c:* EOF
Firewall
Although I would be keen to use the default 'firewalld', it just doesn't seem to be there yet.
# yum install iptables-services iptables-utils # systemctl disable firewalld.service # systemctl stop firewalld.service # systemctl enable iptables.service # systemctl enable ip6tables.service # systemctl start iptables.service # systemctl start ip6tables.service
Add the default firewall configuration files from the appendices. Add 'nf_conntrack_ftp' to /etc/sysconfig/iptables-config and /etc/sysconfig/ip6tables-config.
yum-cron
Enable updates to be applied:
# sed -ie 's/apply_updates = no/apply_updates = yes/' /etc/yum/yum-cron.conf
Links
- http://linux-pam.org/Linux-PAM-html/sag-pam_env.html
- https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/main-analyzeperf-tuned.html
Appendices
iptables
# # firewall config for xen vm # *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] :icmpForward - [0:0] :icmpIn - [0:0] :icmpOut - [0:0] :tcpForward - [0:0] :tcpIn - [0:0] :tcpOut - [0:0] :udpForward - [0:0] :udpIn - [0:0] :udpOut - [0:0] # # # Drop any NEW tcp sessions that don't have a syn bit -A tcpIn -p tcp -m tcp ! --syn -m state --state NEW -j DROP # # Established connections # ----------------------- # # TCP -A tcpForward -p tcp -m tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A tcpForward -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A tcpIn -p tcp -m tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A tcpIn -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A tcpOut -p tcp -m tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A tcpOut -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT # # UDP -A udpForward -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A udpForward -p udp -m udp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A udpIn -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A udpIn -p udp -m udp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A udpOut -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A udpOut -p udp -m udp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT # # ICMP -A icmpForward -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A icmpIn -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A icmpOut -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # SSH in -A tcpIn -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT # -A tcpOut -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT -A tcpOut -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT -A tcpOut -p tcp -m tcp --dport 3128 -m conntrack --ctstate NEW -j ACCEPT # # Mail out -A tcpOut -p tcp -m tcp --dport 25 -m conntrack --ctstate NEW -j ACCEPT # # DNS out -A tcpOut -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT -A udpOut -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT # # ICMP - echo request -A icmpIn -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT -A icmpOut -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT # # Append the chains to the main chains # ==================================== # -A INPUT --source 127.0.0.1 --destination 127.0.0.1 -j ACCEPT -A OUTPUT --source 127.0.0.1 --destination 127.0.0.1 -j ACCEPT # -A FORWARD -p tcp -j tcpForward -A INPUT -p tcp -j tcpIn -A OUTPUT -p tcp -j tcpOut -A FORWARD -p udp -j udpForward -A INPUT -p udp -j udpIn -A OUTPUT -p udp -j udpOut -A FORWARD -p icmp -j icmpForward -A INPUT -p icmp -j icmpIn -A OUTPUT -p icmp -j icmpOut # # log, drop, and drop again anything not explicitly allowed -A INPUT -j LOG --log-prefix "vm-in " -A OUTPUT -j LOG --log-prefix "vm-out " -A FORWARD -j LOG --log-prefix "vm-forward " # -A INPUT --jump DROP -A OUTPUT --jump DROP -A FORWARD --jump DROP COMMIT
ip6tables
# # IPv6 firewall config for xen vm # *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] :icmpIn - [0:0] :icmpOut - [0:0] :tcpIn - [0:0] :tcpOut - [0:0] :udpIn - [0:0] :udpOut - [0:0] # # Drop any NEW tcp sessions that don't have a syn bit -A tcpIn -p tcp -m tcp ! --syn -m conntrack --ctstate NEW -j DROP # # Established connections # ----------------------- # # TCP -A tcpIn -p tcp -m tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A tcpIn -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A tcpOut -p tcp -m tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A tcpOut -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT # # UDP -A udpIn -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A udpIn -p udp -m udp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT -A udpOut -p udp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A udpOut -p udp -m udp --sport 1024:65535 --dport 1024:65535 -m conntrack --ctstate RELATED -j ACCEPT # # ICMP -A icmpIn -p icmpv6 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A icmpOut -p icmpv6 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # SSH in -A tcpIn -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT # http/squid -A tcpOut -p tcp -m tcp --dport 3128 -m conntrack --ctstate NEW -j ACCEPT -A tcpOut -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT -A tcpOut -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT # SMTP out -A tcpOut -p tcp -m tcp --dport 25 -m conntrack --ctstate NEW -j ACCEPT # DNS out -A tcpOut -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT -A udpOut -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT # ICMP # ==== # type #1 -A icmpIn -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT # type #2 -A icmpIn -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT # type #3 -A icmpIn -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT # type #4 -A icmpIn -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT # type #128/129 -A icmpIn -p icmpv6 --icmpv6-type echo-request -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type echo-request -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type echo-reply -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type echo-reply -j ACCEPT # type #134 -A icmpIn -p icmpv6 --source fe80::/10 --icmpv6-type 134 -j ACCEPT # Neighbor solicatation -A icmpIn -p icmpv6 --icmpv6-type 135 -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type 135 -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type 136 -j ACCEPT -A icmpOut -p icmpv6 --icmpv6-type 136 -j ACCEPT # type #134 -A icmpOut -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT # type #135 -A icmpOut -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT # type #136 -A icmpOut -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT # type #137 -A icmpOut -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT -A icmpIn -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT # type #143 -A icmpIn -p icmpv6 --source fe80::/10 --icmpv6-type 143 -j ACCEPT -A icmpOut -p icmpv6 --destination ff02::/16 --icmpv6-type 143 -j ACCEPT # # Append the chains to the main chains # ==================================== # -A INPUT --source ::1/128 --destination ::1/128 -j ACCEPT -A OUTPUT --source ::1/128 --destination ::1/128 -j ACCEPT # -A INPUT -p tcp -j tcpIn -A OUTPUT -p tcp -j tcpOut -A INPUT -p udp -j udpIn -A OUTPUT -p udp -j udpOut -A INPUT -p icmpv6 -j icmpIn -A OUTPUT -p icmpv6 -j icmpOut # # log, drop, and drop again anything not explicitly allowed -A INPUT -j LOG --log-prefix "vm-6in " -A OUTPUT -j LOG --log-prefix "vm-6out " -A FORWARD -j LOG --log-prefix "vm-6forward " # -A INPUT --jump DROP -A OUTPUT --jump DROP -A FORWARD --jump DROP COMMIT