Новый датацентр. Сервер.

Долго ли, коротко, но дошел я до того, что мне стало уж очень дорого пользоваться услугами Amazon. Оно удобно, но дорого. Значит, мне опять дорога назад, к выделенному серверу.

Но терять кучку удобных штук типа докера нет желания, поэтому буду строить сразу и с запасом. Итак, что мне охота

1. Централизованное управление аккаунтами. Для всяких ssh, git и прочим
2. KVM и докер.
3. Чистый, не засранный хост. Не хочу видеть по интерфейсу и 10 правил на каждый контейнер.
4. Разное.

Итак, стадия номер 1 или “подготовка”. Все использованное мной можно найти тут: https://github.com/kiltum/newdc Ну и я подозреваю, что вы уже имеете опыт администрирования linux, поэтому буду только намечать путь.

Арендую новый сервер. Hetzner, leaseweb – их много. И ставлю туда пустую и голую CentOS 7. Никаких панелей, рюшечек и прочего. Из моих уже личных требований – поставить все на raid1.

Бутстраплю ее с помощью ansible и роли centos-bootstrap.yml. Там снос selinux, firewalld, установка ntp и прочих пакетиков и обновление системы. Самый необходимый минимум.

Ставлю KVM. Эта операция одноразовая, поэтому можно и руками.

yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install

Сношу дефаултную сеть от KVM. Это автоматически избавляет меня от кучки правил в iptables.

virsh net-autostart --disable default
virsh net-destroy default

Создаю тупой интерфейс, куда буду цеплять с помощью бриджа виртуалки

modprobe dummy numdummies=1
echo "dummy" > /etc/modules-load.d/dummy.conf
echo "options dummy numdummies=1" >> /etc/modprobe.d/dummy.conf

Генерирую для него мак-адресс (в принципе можно от балды, но лучше что бы с первыми октетами от KVM – так симпатичней)

hexdump -vn3 -e '/3 "52:54:00"' -e '/1 ":%02x"' -e '"\n"' /dev/urandom

И делаю конфиг-фаил для этого интерфейса

cat > /etc/sysconfig/network-scripts/ifcfg-dummy0
DEVICE=dummy0
MACADDR=52:54:00:1b:e1:80
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
BRIDGE=virbr100

и описываю бридж

cat > /etc/sysconfig/network-scripts/ifcfg-virbr100
DEVICE=virbr100
NAME=virbr100
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Bridge
DELAY=2
STP=on
IPADDR=172.16.100.1
NETMASK=255.255.255.0
IPV6INIT=no

Поднимаю созданное

ifup virbr100

В результате я получил следующее

2: dummy0: mtu 1500 qdisc noqueue master virbr100 state UNKNOWN qlen 1000
link/ether 52:54:00:1b:e1:80 brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fe1b:e180/64 scope link
valid_lft forever preferred_lft forever
...
5: virbr100: mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 52:54:00:1b:e1:80 brd ff:ff:ff:ff:ff:ff
inet 172.16.100.1/24 brd 172.16.100.255 scope global virbr100
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe1b:e180/64 scope link
valid_lft forever preferred_lft forever

Разрешаю форвардинг пакетиков между интерфейсами

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.forwarding=1" >> /etc/sysctl.conf
sysctl -p

Для полноценной работы виртуалок я добавляю в стандартный набор правил еще одно, которое обеспечивает виртуалкам выход в интернет. Вместо иксиков подставьте свой внешний ipшник

-A POSTROUTING -o eth0 -j SNAT --to-source x.x.x.x

И в принципе все, я готов создать первую виртуалку.

virt-install --name head.ka12.ko --network bridge=virbr100 --memory 1024 --disk path=head.ka12.co.img,size=30 --cdrom ../iso/CentOS-7-x86_64-Minimal-1708.iso --graphics vnc,listen=172.16.100.1 --noautoconsole

И получаю к ней доступ по VNC

virsh vncdisplay head.ka12.co

Так как пока нету ничего даже похожего на нормальный доступ, пробрасываю VNC порт на локальную машину

ssh -L 5901:172.16.100.1:5900 kiltum@ka12.co

Дальше открываю VNC клиент и по адресу localhost:5901 получаю консоль виртуалки. Дальше как обычно “Далее-далее-подождать и перезагрузить”. Опять же можно было заморочиться и использовать автостарты, но мне лень такое делать на редких и одноразовых операциях.

У этой новой виртуалки будет совершенно ожидаемый адрес 172.16.100.2. После “ребута” инсталлятора снова запускаем и ставим в автозапуск

virsh start head.ka12.co
virsh autostart head.ka12.co

Первым делом надо решить вопрос с доступом в мою “инфраструктуру”. Тут пока ничего лучше не придумали, как openvpn. Запихиваю в /etc/resolv.conf временный адрес DNS сервера и начинаю

yum -y install epel-release mc
yum -y install openvpn easy-rsa

Меняю конфиги openvpn

cat server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 172.16.101.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.16.0.0 255.255.0.0"
;push "redirect-gateway def1 bypass-dhcp"
;push "dhcp-option DNS 172.16.100.2"
;push "dhcp-option DOMAIN ka12.co"
duplicate-cn
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
verb 3

Обратите внимание, специально закомментировал некоторые строки, которые понадобятся в будущем. Теперь генерирую ключи

mkdir -p /etc/openvpn/easy-rsa/keys
cp -rf /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa
mcedit /etc/openvpn/easy-rsa/vars
cp /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca
./build-key-server server
./build-dh
cd /etc/openvpn/easy-rsa/keys
cp dh2048.pem ca.crt server.crt server.key /etc/openvpn
cd /etc/openvpn/easy-rsa
./build-key client

Разрешаю форвардинг

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.forwarding=1" >> /etc/sysctl.conf
sysctl -p

и запускаю openvpn

systemctl enable openvpn@server.service
systemctl start openvpn@server.service

так как там все по умолчанию, очищаю правила фаерволла на виртуалке

iptables -F

Все, теперь на хосте надо открыть порт 1194/udp и пробросить его на виртуалку

-A PREROUTING -d x.x.x.x/32 -i eth0 -p udp --dport 1194 -j DNAT --to-destination 172.16.100.2
-A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT

Добавляю роутинг до подсети vpn

ip route add 172.16.101.0/24 via 172.16.100.2

cat > /etc/sysconfig/network-scripts/route-virbr100
172.16.101.0/24 via 172.16.100.2 dev virbr100

Делаю темплейт клиентского конфига

cat client.template
client
dev tun
proto udp
remote vpn.ka12.co 1194
resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo
verb 3
key-direction 1
remote-cert-tls server
mssfix
<ca>
ca.crt
</ca>
<cert>
client.crt
</cert>
<key>
client.key
</key>
<tls-auth>
ta.key
</tls-auth>

И заполняю его (в дальнейшем я сделал маленький скрипт gen_config.sh)

sed -e '/ca.crt/rca.crt' -e '/client.crt/reasy-rsa/keys/client.crt' -e '/client.key/reasy-rsa/keys/client.key' -e '/ta.key/rta.key' -e '/crt/d' -e '/\.key/d' client.template | sed -e 's/#.*$//' -e '/^$/d' > cl.ovpn

Цепляюсь и проверяю доступность хоста через vpn

traceroute 172.16.100.1
traceroute to 172.16.100.1 (172.16.100.1), 64 hops max, 52 byte packets
1 172.16.101.1 (172.16.101.1) 53.941 ms 48.797 ms 47.938 ms
2 172.16.100.1 (172.16.100.1) 49.186 ms !Z 48.813 ms !Z 49.865 ms !Z

Пробрасываю ключ, бутстраплю виртуалку и ставлю в ней FreeIPA
ssh-copy-id root@172.16.100.2

ansible-playbook -i inventory -l head.ka12.co centos-bootstrap.yml

yum -y install ipa-server bind bind-dyndb-ldap ipa-server-dns

ipa-server-install --setup-dns --mkhomedir --allow-zone-overlap

Меняю шелл по умолчанию

kinit admin
ipa config-mod --defaultshell=/bin/bash

Внезапно оказалось, что FreeIPA с 1 гигом памяти стартует очень тяжко. Добавляю памяти

virsh setmaxmem head.ka12.co 4G --config
virsh setmem head.ka12.co 2G --config

И включаю VPN на полную

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 172.16.100.2"
push "dhcp-option DOMAIN ka12.co"

Добавляю pam сервис

cd /etc/pam.d/
ln -s system-auth openvpn

Добавляю группу openvpn и sshd и заношу в нее меня. В принципе все тоже самое можно сделать через веб-интерфес FreeIPA.

ipa hbacsvc-add openvpn
ipa hbacrule-add allow_openvpn
ipa hbacrule-add-service allow_openvpn --hbacsvcs=openvpn
ipa hbacrule-add-user allow_openvpn --user=kiltum
ipa hbacrule-add-service allow_sshd --hbacsvcs=sshd
ipa hbacrule-add-user allow_sshd --user=kiltum
ipa hbacrule-add-host allow_sshd --hosts=head.ka12.co
ipa hbactest --user=kiltum --host=head.ka12.co --service=sshd

Теперь остался последний шаг. Добавляю в конфиг сервера

plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn

а в конфиг клиента

auth-user-pass

И всё.

В случае проблем проверить работу авторизации можно и прямо на стороне сервера:

pamtester openvpn kiltum authenticate

Что же получил на данном этапе?

1. Хост, на котором крутится только KVM и больше ничего. А значит: ошибиться негде, ломать тоже особо нечего.
2. OpenVPN, доступ до которого защищен сразу двумя методами: клиентским сертификатом и логином-паролем.
3. Внутренний DNS, который снаружи никак не виден.
4. Управление пользователями/группами/сервисами. Располагается исключительно во внутренней сети.
5. Даже если опустить везде фаирволлы, то ничего нового не будет доступно снаружи.

Игрища с сервером – 1

Или даешь централизацию! Сервер установлен, некоторые виртуалки перенесены, а некоторые удалены. Надо облегчать себе жизнь.

Уже сейчас на хосте размещено с десяток виртуалок. И уже сейчас всеми ими рулить скучно. Зашел на одну, обновил, сходил на другую, обновил. А пароли поменять? А дать доступ очередному фрилансеру и потом не забыть его отобрать? В общем, тяжело. Было.

Первым делом надо поставить единую систему авторизации. Что бы все пароли были в одном месте и думать не надо было. Так как основной системой везде у меня CentOS, то самым логичным кандидатом на эту тему становится FreeIPA.

Раньше я на нее взглянуть без слез не мог, а теперь она выросла во вполне себе крутую систему, умеющую все, что необходимо системам такого рода. Начнем. Этап установки еще одной виртуалки я пропускаю.

yum -y install ipa-server bind bind-dyndb-ldap ipa-server-dns
ipa-server-install --setup-dns --mkhomedir

Если что-то где-то накосячили (а вы в первый раз обязательно накосячите), то всегда можно убрать все в первоначальное состояние.
ipa-server-install --uninstall

В процессе установки у меня спросили два пароля – самого главного и админа. Плюс отказался от dns-forwarders (ибо пока в них смысла нет, но если надо, то потом можно поставить), а дальше просто соглашался со всем. Как увидите бегущие пунктики – значит вы прорвались и скоро получите настроенную систему.

Итак, оно вроде сказало, что готово. Чего делаем? Первым делом – сделаем, что бы у пользователей по умолчанию был шелл /bin/bash, а не /bin/sh.

kinit admin
ipa config-mod --defaultshell=/bin/bash

И добавлю себя любимого

# ipa user-add
First name: Viacheslav
Last name: Kaloshin
User login [vkaloshin]: multik
-------------------
Added user "multik"
-------------------
User login: multik
First name: Viacheslav
Last name: Kaloshin
Full name: Viacheslav Kaloshin
Display name: Viacheslav Kaloshin
Initials: VK
Home directory: /home/multik
GECOS: Viacheslav Kaloshin
Login shell: /bin/bash
Kerberos principal: multik@LOCAL.MULTIK.ORG
Email address: multik@local.multik.org
UID: 1624000001
GID: 1624000001
Password: False
Member of groups: ipausers
Kerberos keys available: False

и поменяем пароль мне (в принципе можно было это сделать и сразу, но так интересней)

# ipa user-mod multik --password
Password:
Enter Password again to verify:
----------------------
Modified user "multik"
----------------------
User login: multik
First name: Viacheslav
Last name: Kaloshin
Home directory: /home/multik
Login shell: /bin/bash
Email address: multik@local.multik.org
UID: 1624000001
GID: 1624000001
Account disabled: False
Password: True
Member of groups: ipausers
Kerberos keys available: True

Теперь в принципе можно проверить, залогинившись на хост свежесозданным пользователем

# ssh multik@10.100.0.10
multik@10.100.0.10's password:
Password expired. Change your password now.
Creating home directory for multik.
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user multik.
Current Password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Connection to 10.100.0.10 closed.

Как видим, система принудительно заставляет пользователя сменить пароль. Это хорошо.

В принципе, можно все необходимое делать из консоли, а можно и с веб-интерфейса – просто браузером сходите и все сами увидите.

Но это только начало. Нам надо к этой системе подключить остальные виртуалки. Для этого надо сделать две простые вещи: настроить DNS и поставить клиента ipa. Пока для проверки, я это сделаю только на одном хосте.

на виртуалке:

# cat /etc/resolv.conf
search local.multik.org
nameserver 10.100.0.10
nameserver 10.100.0.254

на ipa надо открыть днс:

firewall-cmd --permanent --add-port=53/tcp
firewall-cmd --permanent --add-port=53/udp
firewall-cmd --reload

и опять на виртуалке

# ping ipa -c 2
PING ipa.local.multik.org (10.100.0.10) 56(84) bytes of data.
64 bytes from ipa.local.multik.org (10.100.0.10): icmp_seq=1 ttl=64 time=0.344 ms
64 bytes from ipa.local.multik.org (10.100.0.10): icmp_seq=2 ttl=64 time=0.461 ms

--- ipa.local.multik.org ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.344/0.402/0.461/0.061 ms

Отлично. Теперь подключим виртуалку

На ipa

firewall-cmd --permanent --add-service={ntp,http,https,ldap,ldaps,kerberos,kpasswd}
firewall-cmd --reload

на виртуалке

yum install -y ipa-client
# ipa-client-install --mkhomedir
Discovery was successful!
Client hostname: vsemoe-com.local.multik.org
Realm: LOCAL.MULTIK.ORG
DNS Domain: local.multik.org
IPA Server: ipa.local.multik.org
BaseDN: dc=local,dc=multik,dc=org

Continue to configure the system with these values? [no]: yes
Synchronizing time with KDC...
Attempting to sync time using ntpd. Will timeout after 15 seconds
User authorized to enroll computers: admin
Password for admin@LOCAL.MULTIK.ORG:
Successfully retrieved CA cert
Subject: CN=Certificate Authority,O=LOCAL.MULTIK.ORG
Issuer: CN=Certificate Authority,O=LOCAL.MULTIK.ORG
Valid From: Mon Jan 25 12:03:20 2016 UTC
Valid Until: Fri Jan 25 12:03:20 2036 UTC

Enrolled in IPA realm LOCAL.MULTIK.ORG
Created /etc/ipa/default.conf
New SSSD config will be created
Configured sudoers in /etc/nsswitch.conf
Configured /etc/sssd/sssd.conf
Configured /etc/krb5.conf for IPA realm LOCAL.MULTIK.ORG
trying https://ipa.local.multik.org/ipa/json
Forwarding 'ping' to json server 'https://ipa.local.multik.org/ipa/json'
Forwarding 'ca_is_enabled' to json server 'https://ipa.local.multik.org/ipa/json'
Systemwide CA database updated.
Added CA certificates to the default NSS database.
Hostname (vsemoe-com.local.multik.org) does not have A/AAAA record.
Missing reverse record(s) for address(es): 10.100.0.178, 2a01:4f8:171:1a43:5054:ff:fe51:f70e.
Adding SSH public key from /etc/ssh/ssh_host_rsa_key.pub
Adding SSH public key from /etc/ssh/ssh_host_ecdsa_key.pub
Adding SSH public key from /etc/ssh/ssh_host_ed25519_key.pub
Forwarding 'host_mod' to json server 'https://ipa.local.multik.org/ipa/json'
SSSD enabled
Configured /etc/openldap/ldap.conf
NTP enabled
Configured /etc/ssh/ssh_config
Configured /etc/ssh/sshd_config
Configuring local.multik.org as NIS domain.
Client configuration complete.

При этом процессе, сразу создадутся и прямые записи в днс. Почему и как создавать сразу и обратные – я не разбирался.

[root@ipa ~]# host vsemoe-com
vsemoe-com.local.multik.org has address 10.100.0.178
vsemoe-com.local.multik.org has IPv6 address 2a01:4f8:171:1a43:5054:ff:fe51:f70e

Проверяю, как оно работает

[root@tower ~]# ssh multik@10.100.0.178
multik@10.100.0.178's password:
Creating home directory for multik.
[multik@vsemoe-com ~]$ whoami
multik
[multik@vsemoe-com ~]$ id
uid=1624000001(multik) gid=1624000001(multik) groups=1624000001(multik) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Как вижу, работает отлично. Пока я остановлюсь на этом шаге. Ибо мне нужен нормальный удаленный доступ, а то потом слишком много придется переделывать.