Manage multiple server & client computers with SaltStack (finnish)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1064 lines
35 KiB

  1. Palvelinten hallinta - Harjoitus 2
  2. ==============
  3. *Disclaimer:*
  4. --------------
  5. Tämä harjoitus on tehty osana Haaga-Helian Tietojenkäsittelyn koulutusohjelman kurssia [Palvelinten hallinta (ICT4TN022, kevät 2018)](http://www.haaga-helia.fi/fi/opinto-opas/opintojaksokuvaukset/ICT4TN022). Kurssin pitäjänä toimii [Tero Karvinen](http://terokarvinen.com/), joka on määritellyt tämän harjoituksen tehtävänkuvaukset. Tehtävien vastaukset ovat Pekka Heleniuksen (allekirjoittanut) tuottamia.
  6. *SISÄLLYSLUETTELO*
  7. --------------
  8. - [b) Laita käyttäjien kotisivut toimimaan Apachella - Salt](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h2.md#b-laita-k%C3%A4ytt%C3%A4jien-kotisivut-toimimaan-apachella---salt)
  9. - [c) Laita PHP toimimaan käyttäjien kotisivuilla - Salt (Huomaa, että PHP toimii oletuksena kaikkialla muualla kuin käyttäjien public_html-kotisivuilla.)](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h2.md#c-laita-php-toimimaan-k%C3%A4ytt%C3%A4jien-kotisivuilla---salt-huomaa-ett%C3%A4-php-toimii-oletuksena-kaikkialla-muualla-kuin-k%C3%A4ytt%C3%A4jien-public_html-kotisivuilla)
  10. - [d) Rakenna tila (state), joka tekee Apachelle uuden nimipohjaisen virtuaalipalvelimen (name based virtual hosting). Voit simuloida nimipalvelun toimintaa hosts-tiedoston avulla.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h2.md#d-rakenna-tila-state-joka-tekee-apachelle-uuden-nimipohjaisen-virtuaalipalvelimen-name-based-virtual-hosting-voit-simuloida-nimipalvelun-toimintaa-hosts-tiedoston-avulla)
  11. - [e) Tee tila, joka laittaa esimerkkikotisivun uusille käyttäjille. Voit laittaa esimerkkikotisivu /etc/skel/:iin, niin se tulee automaattisesti ‘adduser tero’ komennolla käyttäjiä luodessa.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h2.md#e-tee-tila-joka-laittaa-esimerkkikotisivun-uusille-k%C3%A4ytt%C3%A4jille-voit-laittaa-esimerkkikotisivu-etcskeliin-niin-se-tulee-automaattisesti-adduser-tero-komennolla-k%C3%A4ytt%C3%A4ji%C3%A4-luodessa)
  12. - [f) Eri asetukset. Tee Package-File-Service tilalla eri asetuksia kuin ne, mitä tehtiin tunnilla; ja eri kuin mitä teit/teet h2 muissa kohdissa. Voit muuttaa jotain toista asetusta samoista demoneista tai valita kokonaan eri demonit.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h2.md#f-eri-asetukset-tee-package-file-service-tilalla-eri-asetuksia-kuin-ne-mit%C3%A4-tehtiin-tunnilla-ja-eri-kuin-mit%C3%A4-teitteet-h2-muissa-kohdissa-voit-muuttaa-jotain-toista-asetusta-samoista-demoneista-tai-valita-kokonaan-eri-demonit)
  13. b) Laita käyttäjien kotisivut toimimaan Apachella - Salt
  14. --------------
  15. **Vastaus:**
  16. Olemme tässä vaiheessa luoneet perusedellytykset Masterille ja Minione(ille). Ks. [harjoitus 1](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h1.md)
  17. Luodaan Master-koneen kansioon _/srv/salt_ state-tiedosto *0_create_indexhtml.sls* komennolla *sudo nano /srv/salt/0_create_indexhtml.sls* ja täydennetään se sisällöllä:
  18. ```
  19. # This is a Salt script for installing Apache HTTP daemon with
  20. # default userdir configuration to minion computers
  21. # Author: Pekka Helenius (~Fincer), 2018
  22. #########################################
  23. # Install Apache HTTP daemon to minions
  24. install_httpd_daemon:
  25. pkg.installed:
  26. - pkgs:
  27. - apache2
  28. #########################################
  29. # Enable Apache userdir module
  30. httpd_userdir:
  31. cmd.run:
  32. - name: /usr/sbin/a2enmod userdir
  33. - require:
  34. - pkg: install_httpd_daemon
  35. #########################################
  36. # Replace default index.html content
  37. httpd_foo-index:
  38. cmd.run:
  39. - name: /bin/echo "foo" > /var/www/html/index.html
  40. - require:
  41. - cmd: httpd_userdir
  42. - pkg: install_httpd_daemon
  43. #########################################
  44. # Execute public_html script
  45. execute_public_html:
  46. cmd.script:
  47. - name: salt://0_create_indexhtml.sh
  48. - runas: root
  49. #########################################
  50. # Restart Apache HTTP daemon
  51. httpd_service_restart_userdir:
  52. service.running:
  53. - name: apache2.service
  54. - watch:
  55. - cmd: httpd_userdir
  56. ```
  57. Tiedoston oikeudet tulisi olla: u=rw, g=r, o=r (0644)
  58. Harjoituksessa käytetään Debian-pohjaisia Xubuntu-käyttöjärjestelmiä (18.04 LTS).
  59. Varmistetaan, että "orja" -alkuisiin orjakoneisiin (minions) saadaan yhteys suorittamalla master-koneella esim. komento:
  60. ```
  61. [09/04/2018 22:01:26 - fincer: ~ ]$ sudo salt 'orja*' grains.item osrelease
  62. orjakone:
  63. ----------
  64. osrelease:
  65. 18.04
  66. ```
  67. Luodaan master-koneelle seuraava shell-skripti */srv/salt/0_create_indexhtml.sh*, joka tuottaa kaikille orjakoneen käyttäjille kansion *public_html* testisivuineen:
  68. ```
  69. #!/bin/sh
  70. # Find home folders of system users (who are using bash as their default shell)
  71. for userhome in $(grep -E "\/bin\/bash" /etc/passwd | grep -v root | awk -F ':' '{print $(NF - 1)}'); do
  72. # Create public_html for found user
  73. if [ ! -d "${userhome}"/public_html ]; then
  74. mkdir -p "${userhome}"/public_html
  75. # Promote this user to be the owner of the created directory
  76. chown $(stat --format "%u:%g" ${userhome}) "${userhome}"/public_html
  77. # Touch default index file for testing purposes
  78. echo "This is my test site. I am user $(stat --format \"%U\" ${userhome}). Happy coding!" > "${userhome}"/public_html/index.html
  79. fi
  80. done
  81. ```
  82. Suoritetaan tehtävänannossa edellytetty Apache HTTP-daemonin asennus minion-koneille:
  83. ```
  84. sudo salt 'orja*' state.apply 0_create_indexhtml
  85. ```
  86. Esimerkki-output (masterilla):
  87. ```
  88. [09/04/2018 21:45:41 - fincer: salt ]$ sudo salt 'orja*' state.apply 0_create_indexhtml
  89. orjakone:
  90. ----------
  91. ID: install_httpd_daemon
  92. Function: pkg.installed
  93. Result: True
  94. Comment: All specified packages are already installed
  95. Started: 03:06:06.583325
  96. Duration: 377.198 ms
  97. Changes:
  98. ----------
  99. ID: httpd_userdir
  100. Function: cmd.run
  101. Name: /usr/sbin/a2enmod userdir
  102. Result: True
  103. Comment: Command "/usr/sbin/a2enmod userdir" run
  104. Started: 03:06:06.962361
  105. Duration: 19.784 ms
  106. Changes:
  107. ----------
  108. pid:
  109. 20406
  110. retcode:
  111. 0
  112. stderr:
  113. stdout:
  114. Module userdir already enabled
  115. ----------
  116. ID: httpd_foo-index
  117. Function: cmd.run
  118. Name: /bin/echo "foo" > /var/www/html/index.html
  119. Result: True
  120. Comment: Command "/bin/echo "foo" > /var/www/html/index.html" run
  121. Started: 03:06:06.982499
  122. Duration: 3.978 ms
  123. Changes:
  124. ----------
  125. pid:
  126. 20411
  127. retcode:
  128. 0
  129. stderr:
  130. stdout:
  131. ----------
  132. ID: execute_public_html
  133. Function: cmd.script
  134. Name: salt://0_create_indexhtml.sh
  135. Result: True
  136. Comment: Command 'salt://0_create_indexhtml.sh' run
  137. Started: 03:06:06.986594
  138. Duration: 415.176 ms
  139. Changes:
  140. ----------
  141. pid:
  142. 20432
  143. retcode:
  144. 0
  145. stderr:
  146. stdout:
  147. ----------
  148. ID: httpd_service_restart_userdir
  149. Function: service.running
  150. Name: apache2.service
  151. Result: True
  152. Comment: Service restarted
  153. Started: 03:06:07.435663
  154. Duration: 124.998 ms
  155. Changes:
  156. ----------
  157. apache2.service:
  158. True
  159. Summary for orjakone
  160. ------------
  161. Succeeded: 5 (changed=4)
  162. Failed: 0
  163. ------------
  164. Total states run: 5
  165. Total run time: 941.134 ms
  166. ```
  167. Minion-koneelta voimme tarkastaa, onko kansio *public_html* ja tiedosto *index.html* luotu (esim. orjakone:en käyttäjälle fincer):
  168. ```
  169. [09/04/2018 21:46:59 - fincer: salt ]$ sudo salt 'orjakone' cmd.run 'cat /home/fincer/public_html/index.html'
  170. orjakone:
  171. This is my test site. I am user "fincer". Happy coding!
  172. ```
  173. c) Laita PHP toimimaan käyttäjien kotisivuilla - Salt (Huomaa, että PHP toimii oletuksena kaikkialla muualla kuin käyttäjien public_html-kotisivuilla.)
  174. --------------
  175. **Vastaus:**
  176. Tehtävässä pitää orjakoneilta (minions) kytkeä PHP päälle userdir-moduulin kanssa editoimalla konfiguraatiotiedostoa /etc/apache2/mods-available/php*.conf (missä * on php-versio).
  177. Tämä vaihe voidaan tehdä kahdella tavalla:
  178. - 1) Luodaan master-koneelle uusi konfiguraatiotiedosto (php*.conf) samalla sisällöllä, mutta kommentoidaan userdir-moduulin edellyttämät rivit tiedostosta (tiedostossa on selkeät ohjeet tähän)
  179. - 2) Luodaan skripti, jonka tehtävänä on lisätä kommenttimerkit orjakoneiden php*.conf -tiedoston relevanttiin osioon
  180. Molemmat vaihtoehdot määritetään suoritettavaksi master:lla Saltin state-tiedostossa. Toteutetaan vaihtoehto 2.
  181. Luodaan master-koneella shell-skripti */srv/salt/1_enable_php-for-userdir.sh* sisällöllä:
  182. ```
  183. #!/bin/sh
  184. # Enable PHP for userdir module in Apache
  185. # Author: Pekka Helenius, 2018
  186. PHP_CONF_FILE="$(ls /etc/apache2/mods-available/php*.conf)"
  187. IFS="
  188. "
  189. for line in $(cat "${PHP_CONF_FILE}" | sed -n '/\<IfModule mod_userdir\.c>/,/\<\/IfModule>/p;/\<\/IfModule>/q'); do
  190. sed_line=$(echo "${line}" | sed 's!\*!\\*!g;')
  191. sed -ir "s!${sed_line}!#${sed_line}!" "${PHP_CONF_FILE}"
  192. done
  193. unset IFS
  194. ```
  195. Luodaan master-koneella toinenkin shell-skripti */srv/salt/1_create_indexphp.sh* seuraavalla sisällöllä:
  196. ```
  197. #!/bin/sh
  198. # Find home folders of system users (who are using bash as their default shell)
  199. for userhome in $(grep -E "\/bin\/bash" /etc/passwd | grep -v root | awk -F ':' '{print $(NF - 1)}'); do
  200. # Create public_html for found user
  201. if [ ! -d "${userhome}"/public_html ]; then
  202. mkdir -p "${userhome}"/public_html
  203. # Promote this user to be the owner of the created directory
  204. chown $(stat --format "%u:%g" ${userhome}) "${userhome}"/public_html
  205. # Rename existing index.html if exists
  206. if [ -f "${userhome}"/public_html/index.html ]; then
  207. mv "${userhome}"/public_html/index.html "${userhome}"/public_html/index.html.old
  208. fi
  209. # Touch default index PHP file for testing purposes
  210. echo "<?php print('This is PHP code. I am user $(stat --format \"%U\" ${userhome}). Happy coding!'); ?>" > "${userhome}"/public_html/index.php
  211. fi
  212. done
  213. ```
  214. Luodaan master-koneelle state-määritystiedosto */srv/salt/1_create_indexphp.sls* sisällöllä:
  215. ```
  216. # Author: Pekka Helenius (~Fincer), 2018
  217. #########################################
  218. # Variables
  219. # PHP module for Apache in Debian
  220. {% set ENABLE_PHP_MODULE = "/usr/sbin/a2enmod $(a2query -m | awk '{print $1}' | grep php)" %}
  221. {% set USERDIR_ENABLE_STATUS = "a2query -m | grep userdir | grep 'enabled by' &>/dev/null || /usr/sbin/a2enmod userdir" %}
  222. #########################################
  223. # Install PHP addons for Apache HTTP daemon (with dependencies)
  224. install_httpd_php:
  225. pkg.installed:
  226. - pkgs:
  227. - apache2
  228. - libapache2-mod-php
  229. #########################################
  230. # Find if userdir module is enabled
  231. check_userdir_status:
  232. cmd.run:
  233. - name: {{ USERDIR_ENABLE_STATUS }}
  234. - require:
  235. - pkg: install_httpd_php
  236. #########################################
  237. # Enable PHP for users
  238. execute_userdir_php_script:
  239. cmd.script:
  240. - name: salt://apache/1_enable_php-for-userdir.sh
  241. - runas: root
  242. - require:
  243. - cmd: check_userdir_status
  244. add_indexphp_files:
  245. cmd.script:
  246. - name: salt://apache/1_create_indexphp.sh
  247. - runas: root
  248. - require:
  249. - cmd: execute_userdir_php_script
  250. #########################################
  251. # Enable PHP module (should be done already, though)
  252. enable_httpd_php:
  253. cmd.run:
  254. - name: {{ ENABLE_PHP_MODULE }}
  255. #########################################
  256. # Restart Apache HTTP daemon
  257. httpd_service_restart_php:
  258. service.running:
  259. - name: apache2.service
  260. - watch:
  261. - cmd: check_userdir_status
  262. - cmd: execute_userdir_php_script
  263. ```
  264. Esimerkki-output master-koneella:
  265. ```
  266. [09/04/2018 23:13:27 - fincer: ~ ]$ sudo salt 'orjakone' state.apply 1_create_indexphp
  267. orjakone:
  268. ----------
  269. ID: install_httpd_php
  270. Function: pkg.installed
  271. Result: True
  272. Comment: All specified packages are already installed
  273. Started: 03:12:05.777863
  274. Duration: 387.502 ms
  275. Changes:
  276. ----------
  277. ID: check_userdir_status
  278. Function: cmd.run
  279. Name: a2query -m | grep userdir | grep 'enabled by' &>/dev/null || /usr/sbin/a2enmod userdir
  280. Result: True
  281. Comment: Command "a2query -m | grep userdir | grep 'enabled by' &>/dev/null || /usr/sbin/a2enmod userdir" run
  282. Started: 03:12:06.167690
  283. Duration: 37.4 ms
  284. Changes:
  285. ----------
  286. pid:
  287. 20663
  288. retcode:
  289. 0
  290. stderr:
  291. stdout:
  292. userdir (enabled by site administrator)
  293. ----------
  294. ID: execute_userdir_php_script
  295. Function: cmd.script
  296. Name: salt://1_enable_php-for-userdir.sh
  297. Result: True
  298. Comment: Command 'salt://1_enable_php-for-userdir.sh' run
  299. Started: 03:12:06.206077
  300. Duration: 192.94 ms
  301. Changes:
  302. ----------
  303. pid:
  304. 20690
  305. retcode:
  306. 0
  307. stderr:
  308. stdout:
  309. ----------
  310. ID: add_indexphp_files
  311. Function: cmd.script
  312. Name: salt://1_create_indexphp.sh
  313. Result: True
  314. Comment: Command 'salt://1_create_indexphp.sh' run
  315. Started: 03:12:06.399689
  316. Duration: 142.251 ms
  317. Changes:
  318. ----------
  319. pid:
  320. 20734
  321. retcode:
  322. 0
  323. stderr:
  324. stdout:
  325. ----------
  326. ID: enable_httpd_php
  327. Function: cmd.run
  328. Name: /usr/sbin/a2enmod $(a2query -m | awk '{print $1}' | grep php)
  329. Result: True
  330. Comment: Command "/usr/sbin/a2enmod $(a2query -m | awk '{print $1}' | grep php)" run
  331. Started: 03:12:06.542066
  332. Duration: 68.876 ms
  333. Changes:
  334. ----------
  335. pid:
  336. 20741
  337. retcode:
  338. 0
  339. stderr:
  340. stdout:
  341. Considering dependency mpm_prefork for php7.2:
  342. Considering conflict mpm_event for mpm_prefork:
  343. Considering conflict mpm_worker for mpm_prefork:
  344. Module mpm_prefork already enabled
  345. Considering conflict php5 for php7.2:
  346. Module php7.2 already enabled
  347. ----------
  348. ID: httpd_service_restart_php
  349. Function: service.running
  350. Name: apache2.service
  351. Result: True
  352. Comment: Service restarted
  353. Started: 03:12:06.635009
  354. Duration: 87.188 ms
  355. Changes:
  356. ----------
  357. apache2.service:
  358. True
  359. Summary for orjakone
  360. ------------
  361. Succeeded: 6 (changed=5)
  362. Failed: 0
  363. ------------
  364. Total states run: 6
  365. Total run time: 916.157 ms
  366. ```
  367. d) Rakenna tila (state), joka tekee Apachelle uuden nimipohjaisen virtuaalipalvelimen (name based virtual hosting). Voit simuloida nimipalvelun toimintaa hosts-tiedoston avulla.
  368. --------------
  369. **Vastaus:**
  370. **HUOM!** Tämän olisi voinut tehdä myös luomalla esim. index.html- ja sivustokonfiguraatiotiedostot masterilla, josta ne siirrettäisiin minioneille (file). Nämä määritykset tehdään state-tiedostossa, luonnollisesti. Paljon parempi tapa, jos on esimerkiksi tarkoitus laittaa juuri samansisältöinen _/etc/apache2/sites-available/*.conf_ -tiedosto/template ja samansisältöinen, masterilta päivitettävissä oleva index.html -tiedosto minioneille. Tein nyt huvikseni seuraavalla tavalla, vaikka tiedän, ettei se nyt ihan nappiin menekkään.
  371. Luodaan master-koneen */srv/salt/* -kansioon state/konfiguraatiotiedosto *apache_virtualhost_example.sls* sisällöllä:
  372. ```
  373. # Author: Pekka Helenius (~Fincer), 2018
  374. #########################################
  375. # Install Apache HTTP daemon to minions
  376. install_httpd_daemon:
  377. pkg.installed:
  378. - pkgs:
  379. - apache2
  380. #########################################
  381. copy_httpd_defaultsite:
  382. cmd.run:
  383. - name: '[ ! -f /etc/apache2/sites-available/$(hostname)-example.conf ] && cd /etc/apache2/sites-available && cp 000-default.conf $(hostname)-example.conf || false'
  384. - require:
  385. - pkg: install_httpd_daemon
  386. create_site_rootdir:
  387. cmd.run:
  388. - name: /bin/mkdir -p /var/www/html/$(hostname)
  389. - require:
  390. - pkg: install_httpd_daemon
  391. enable_httpd_servername:
  392. cmd.run:
  393. - name: /bin/sed -i "s/#ServerName www\.example\.com/ServerName $(hostname).example.com/" /etc/apache2/sites-available/$(hostname)-example.conf
  394. - require:
  395. - cmd: copy_httpd_defaultsite
  396. change_defaultsite_root:
  397. cmd.run:
  398. - name: /bin/sed -i "s/DocumentRoot \/var\/www\/html/DocumentRoot \/var\/www\/html\/$(hostname)/" /etc/apache2/sites-available/$(hostname)-example.conf
  399. - require:
  400. - cmd: enable_httpd_servername
  401. enable_httpd_defaultsite:
  402. cmd.run:
  403. - name: /usr/sbin/a2ensite $(hostname)-example.conf
  404. - require:
  405. - cmd: change_defaultsite_root
  406. - cmd: copy_httpd_defaultsite
  407. - pkg: install_httpd_daemon
  408. add_virtualhost_string:
  409. cmd.run:
  410. - name: /bin/echo "127.0.0.1 $(hostname).example.com" > /etc/hosts
  411. - require:
  412. - cmd: enable_httpd_defaultsite
  413. add_defaultsite_indexfile:
  414. cmd.run:
  415. - name: '[ ! -f /var/www/html/$(hostname)/index.html ] && /bin/echo "This is default HTML template for $(hostname) ($(hostname).example.com), created on $(date \"+%d-%m-%Y at %X\")" > /var/www/html/$(hostname)/index.html'
  416. - require:
  417. - cmd: create_site_rootdir
  418. - cmd: add_virtualhost_string
  419. - cmd: enable_httpd_defaultsite
  420. restart_httpd_service:
  421. service.running:
  422. - name: apache2.service
  423. - watch:
  424. - cmd: enable_httpd_defaultsite
  425. - cmd: add_defaultsite_indexfile
  426. ```
  427. Ajetaan em. state masterilta minion-koneelle nimeltä "orjakone" (vain tälle yhdelle koneelle, ei muita orjia nyt!):
  428. ```
  429. [10/04/2018 00:13:12 - fincer: ~ ]$ sudo salt 'orjakone' state.apply apache_virtualhost_example
  430. orjakone:
  431. ----------
  432. ID: install_httpd_daemon
  433. Function: pkg.installed
  434. Result: True
  435. Comment: All specified packages are already installed
  436. Started: 05:20:27.160570
  437. Duration: 360.254 ms
  438. Changes:
  439. ----------
  440. ID: copy_httpd_defaultsite
  441. Function: cmd.run
  442. Name: [ ! -f /etc/apache2/sites-available/$(hostname)-example.conf ] && cd /etc/apache2/sites-available && cp 000-default.conf $(hostname)-example.conf || false
  443. Result: False
  444. Comment: Command "[ ! -f /etc/apache2/sites-available/$(hostname)-example.conf ] && cd /etc/apache2/sites-available && cp 000-default.conf $(hostname)-example.conf || false" run
  445. Started: 05:20:27.522609
  446. Duration: 4.361 ms
  447. Changes:
  448. ----------
  449. pid:
  450. 22444
  451. retcode:
  452. 1
  453. stderr:
  454. stdout:
  455. ----------
  456. ID: create_site_rootdir
  457. Function: cmd.run
  458. Name: /bin/mkdir -p /var/www/html/$(hostname)
  459. Result: True
  460. Comment: Command "/bin/mkdir -p /var/www/html/$(hostname)" run
  461. Started: 05:20:27.527146
  462. Duration: 3.26 ms
  463. Changes:
  464. ----------
  465. pid:
  466. 22446
  467. retcode:
  468. 0
  469. stderr:
  470. stdout:
  471. ----------
  472. ID: enable_httpd_servername
  473. Function: cmd.run
  474. Name: /bin/sed -i "s/#ServerName www\.example\.com/ServerName $(hostname).example.com/" /etc/apache2/sites-available/$(hostname)-example.conf
  475. Result: False
  476. Comment: One or more requisite failed: apache_virtualhost_example.copy_httpd_defaultsite
  477. Changes:
  478. ----------
  479. ID: change_defaultsite_root
  480. Function: cmd.run
  481. Name: /bin/sed -i "s/DocumentRoot \/var\/www\/html/DocumentRoot \/var\/www\/html\/$(hostname)/" /etc/apache2/sites-available/$(hostname)-example.conf
  482. Result: False
  483. Comment: One or more requisite failed: apache_virtualhost_example.enable_httpd_servername
  484. Changes:
  485. ----------
  486. ID: enable_httpd_defaultsite
  487. Function: cmd.run
  488. Name: /usr/sbin/a2ensite $(hostname)-example.conf
  489. Result: False
  490. Comment: One or more requisite failed: apache_virtualhost_example.copy_httpd_defaultsite, apache_virtualhost_example.change_defaultsite_root
  491. Changes:
  492. ----------
  493. ID: add_virtualhost_string
  494. Function: cmd.run
  495. Name: /bin/echo "127.0.0.1 $(hostname).example.com" > /etc/hosts
  496. Result: False
  497. Comment: One or more requisite failed: apache_virtualhost_example.enable_httpd_defaultsite
  498. Changes:
  499. ----------
  500. ID: add_defaultsite_indexfile
  501. Function: cmd.run
  502. Name: [ ! -f /var/www/html/$(hostname)/index.html ] && /bin/echo "This is default HTML template for $(hostname) ($(hostname).example.com), created on $(date \"+%d-%m-%Y at %X\")" > /var/www/html/$(hostname)/index.html
  503. Result: False
  504. Comment: One or more requisite failed: apache_virtualhost_example.add_virtualhost_string, apache_virtualhost_example.enable_httpd_defaultsite
  505. Changes:
  506. ----------
  507. ID: restart_httpd_service
  508. Function: service.running
  509. Name: apache2.service
  510. Result: False
  511. Comment: One or more requisite failed: apache_virtualhost_example.add_defaultsite_indexfile, apache_virtualhost_example.enable_httpd_defaultsite
  512. Changes:
  513. Summary for orjakone
  514. ------------
  515. Succeeded: 2 (changed=2)
  516. Failed: 7
  517. ------------
  518. Total states run: 9
  519. Total run time: 367.875 ms
  520. ```
  521. Hups! Epäonnistumisia, emämunaus. Ihan odotettua, sillä...
  522. ...epäonnistumiset johtuvat siitä, että olen määritellyt tietyt ID:t, kuten tässä tapauksessa ehkä kriittisimpänä copy_httpd_defaultsite:n, palauttamaan komennon suorittamisesta arvon false, mikäli mm. tiedosto $(hostname)-example.conf on jo olemassa. Koska kyseinen ID on riippuvuutena alemmille ID:ille, ja nämä ID:t edelleen riippuvuutena eteenpäin muille ID:lle, syntyy ketjureaktio, jossa epäonnistuneita tiloja tulee suuri määrä. Tässä tapauksessa 7 kpl. Tulos oli odotettu _tässä konfiguraatiossa_.
  523. Orjakoneen selainnäkymässä (*xdg-open http://$(hostname).example.com*) ajettuna lopputulos näyttää tältä:
  524. ![minion-virtualhost](https://raw.githubusercontent.com/Fincer/central-management-of-multiple-servers/master/images/minion-example.png)
  525. e) Tee tila, joka laittaa esimerkkikotisivun uusille käyttäjille. Voit laittaa esimerkkikotisivu /etc/skel/:iin, niin se tulee automaattisesti ‘adduser tero’ komennolla käyttäjiä luodessa.
  526. --------------
  527. **Vastaus:**
  528. **HUOM!** Tämä on osittain tehtynä jo vastauksissa b) ja c) (Mitä on tehty: On luotu jokaiselle käyttäjälle index.html (b) ja PHP:n kytkemisen yhteydessä index.php (c))
  529. **HUOM!** Tässä olisi voinut hyödyntää esim. kansiorakennetta _/srv/salt/apache_, jonne laitettu state-tiedostot. Nyt toimitaan vielä yksinkertaisemmalla pohjalla, minkä takia state-tiedostoissa esiintyy päällekkäisyyttä. Monimutkaisemmissa konfiguraatioissa puu-rakennetta olisi hyvä harkita (mandatory?).
  530. Lisätään state *2_apache_skelsite.sls*, joka lisää esimerkkikotisivun määriteltyjen minion-koneiden hakemistoon _/etc/skel_ (teemme alihakemiston *public_html* tänne state-tiedostossa...):
  531. ```
  532. # Author: Pekka Helenius (~Fincer), 2018
  533. #########################################
  534. # Install Apache HTTP daemon to minions
  535. install_httpd_daemon:
  536. pkg.installed:
  537. - pkgs:
  538. - apache2
  539. #########################################
  540. # Enable Apache userdir module
  541. httpd_userdir:
  542. cmd.run:
  543. - name: /usr/sbin/a2enmod userdir
  544. - require:
  545. - pkg: install_httpd_daemon
  546. #########################################
  547. # Replace default index.html content
  548. httpd_foo-index:
  549. cmd.run:
  550. - name: /bin/echo "foo" > /var/www/html/index.html
  551. - require:
  552. - cmd: httpd_userdir
  553. - pkg: install_httpd_daemon
  554. #########################################
  555. # Restart Apache HTTP daemon
  556. httpd_service_restart_skelsite:
  557. service.running:
  558. - name: apache2.service
  559. - watch:
  560. - cmd: httpd_userdir
  561. #########################################
  562. # Create /etc/skel/public_html
  563. apache_add_skel_html_dir:
  564. cmd.run:
  565. - name: /bin/mkdir -p /etc/skel/public_html
  566. - require:
  567. - service: httpd_service_restart_skelsite
  568. #########################################
  569. # Add index.html
  570. apache_default_userindex_file:
  571. cmd.run:
  572. - name: /bin/echo "Empty HTML template" > /etc/skel/public_html/index.html
  573. - require:
  574. - cmd: apache_add_skel_html_dir
  575. ```
  576. Master-koneen output:
  577. ```
  578. [10/04/2018 01:15:01 - fincer: ~ ]$ sudo salt 'orjakone' state.apply 2_apache_skelsite
  579. orjakone:
  580. ----------
  581. ID: install_httpd_daemon
  582. Function: pkg.installed
  583. Result: True
  584. Comment: All specified packages are already installed
  585. Started: 03:46:46.743389
  586. Duration: 368.537 ms
  587. Changes:
  588. ----------
  589. ID: httpd_userdir
  590. Function: cmd.run
  591. Name: /usr/sbin/a2enmod userdir
  592. Result: True
  593. Comment: Command "/usr/sbin/a2enmod userdir" run
  594. Started: 03:46:47.113788
  595. Duration: 21.611 ms
  596. Changes:
  597. ----------
  598. pid:
  599. 21155
  600. retcode:
  601. 0
  602. stderr:
  603. stdout:
  604. Module userdir already enabled
  605. ----------
  606. ID: httpd_foo-index
  607. Function: cmd.run
  608. Name: /bin/echo "foo" > /var/www/html/index.html
  609. Result: True
  610. Comment: Command "/bin/echo "foo" > /var/www/html/index.html" run
  611. Started: 03:46:47.135793
  612. Duration: 4.274 ms
  613. Changes:
  614. ----------
  615. pid:
  616. 21160
  617. retcode:
  618. 0
  619. stderr:
  620. stdout:
  621. ----------
  622. ID: httpd_service_restart_skelsite
  623. Function: service.running
  624. Name: apache2.service
  625. Result: True
  626. Comment: Service restarted
  627. Started: 03:46:47.161935
  628. Duration: 103.555 ms
  629. Changes:
  630. ----------
  631. apache2.service:
  632. True
  633. ----------
  634. ID: apache_add_skel_html_dir
  635. Function: cmd.run
  636. Name: /bin/mkdir -p /etc/skel/public_html
  637. Result: True
  638. Comment: Command "/bin/mkdir -p /etc/skel/public_html" run
  639. Started: 03:46:47.265901
  640. Duration: 73.066 ms
  641. Changes:
  642. ----------
  643. pid:
  644. 21178
  645. retcode:
  646. 0
  647. stderr:
  648. stdout:
  649. ----------
  650. ID: apache_default_userindex_file
  651. Function: cmd.run
  652. Name: /bin/echo "Empty HTML template" > /etc/skel/public_html/index.html
  653. Result: True
  654. Comment: Command "/bin/echo "Empty HTML template" > /etc/skel/public_html/index.html" run
  655. Started: 03:46:47.341257
  656. Duration: 13.803 ms
  657. Changes:
  658. ----------
  659. pid:
  660. 21185
  661. retcode:
  662. 0
  663. stderr:
  664. stdout:
  665. Summary for orjakone
  666. ------------
  667. Succeeded: 6 (changed=5)
  668. Failed: 0
  669. ------------
  670. Total states run: 6
  671. Total run time: 584.846 ms
  672. ```
  673. Minion-koneelta tarkistusta (master-koneella katsottuna):
  674. ```
  675. [10/04/2018 02:54:51 - fincer: ~ ]$ sudo salt 'orjakone' cmd.run '/bin/ls /etc/skel && [ -d /etc/skel/public_html ] && /bin/cat /etc/skel/public_html/*'
  676. orjakone:
  677. index.html
  678. public_html
  679. Empty HTML template
  680. ```
  681. f) Eri asetukset. Tee Package-File-Service tilalla eri asetuksia kuin ne, mitä tehtiin tunnilla; ja eri kuin mitä teit/teet h2 muissa kohdissa. Voit muuttaa jotain toista asetusta samoista demoneista tai valita kokonaan eri demonit.
  682. --------------
  683. **Vastaus:**
  684. Toteutetaan Knock daemonin (knockd - small port-knock daemon) -asennus.
  685. Luodaan master-koneelle tiedosto */srv/salt/knockd.conf*, joka annetaan valituille minioneille (asennetaan polkuun */etc/knockd.conf*)
  686. Haluttu *knockd.conf*:n sisältö (_/srv/salt/knockd.conf_):
  687. ```
  688. [options]
  689. UseSyslog
  690. [openSSH]
  691. sequence = tcp:7065,udp:2431,tcp:421,tcp:4113
  692. seq_timeout = 5
  693. command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  694. tcpflags = syn
  695. [closeSSH]
  696. sequence = tcp:4113,tcp:421,udp:2431,tcp:7065
  697. seq_timeout = 5
  698. command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  699. tcpflags = syn
  700. ```
  701. Luodaan master-koneelle state-tiedosto _/srv/salt/install_knockd.sls_:
  702. ```
  703. # Author: Pekka Helenius (~Fincer), 2018
  704. #########################################
  705. # Install Knock daemon to minions
  706. check_ssh:
  707. pkg.installed:
  708. - pkgs:
  709. - ssh
  710. install_knockd:
  711. pkg.installed:
  712. - pkgs:
  713. - knockd
  714. # Deliver Knock daemon configuration file to minions
  715. deliver_knockd-conf:
  716. file.managed:
  717. - name: /etc/knockd.conf
  718. - user: root
  719. - group: root
  720. - mode: 644
  721. - source: salt://knockd.conf
  722. - require:
  723. - pkg: install_knockd
  724. # Do not proceed if any SSH sessions are open in minion's side. This is just to avoid any harmful effects
  725. prevent_if_ssh_sessions_open:
  726. cmd.run:
  727. - name: 'if [ $(/bin/netstat -tnpa | grep "ESTABLISHED.*sshd" | wc -l) -gt 0 ]; then false; fi'
  728. - require:
  729. - pkg: check_ssh
  730. # PROCEED ONLY IF NO SSH SESSIONS ARE OPEN
  731. #
  732. # Drop SSH port connections. Use port which is defined in minion's /etc/ssh/sshd_config file
  733. drop_ssh_port:
  734. cmd.run:
  735. - name: /sbin/iptables -A INPUT -p tcp --dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}') -j DROP
  736. - require:
  737. - cmd: prevent_if_ssh_sessions_open
  738. - pkg: check_ssh
  739. - file: deliver_knockd-conf
  740. # Change default SSH port 22 in minion's /etc/knockd.conf file:
  741. post-configure_knockd-conf:
  742. cmd.run:
  743. - name: /bin/sed -i "s/dport 22/dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}')/" /etc/knockd.conf
  744. - require:
  745. - pkg: check_ssh
  746. - file: deliver_knockd-conf
  747. # Enable knockd daemon
  748. enable_knockd_service:
  749. cmd.run:
  750. - name: /bin/systemctl enable knockd.service
  751. - require:
  752. - pkg: install_knockd
  753. # Restart knockd daemon
  754. restart_knockd_service:
  755. service.running:
  756. - name: knockd.service
  757. - watch:
  758. - cmd: post-configure_knockd-conf
  759. ```
  760. Esimerkki-output master-koneella ajettuna:
  761. ```
  762. [10/04/2018 06:17:11 - fincer: ~ ]$ sudo salt 'orjakone' state.apply install_knockd
  763. orjakone:
  764. ----------
  765. ID: check_ssh
  766. Function: pkg.installed
  767. Result: True
  768. Comment: All specified packages are already installed
  769. Started: 06:25:12.849731
  770. Duration: 366.695 ms
  771. Changes:
  772. ----------
  773. ID: install_knockd
  774. Function: pkg.installed
  775. Result: True
  776. Comment: The following packages were installed/updated: knockd
  777. Started: 06:25:13.216541
  778. Duration: 53498.645 ms
  779. Changes:
  780. ----------
  781. knockd:
  782. ----------
  783. new:
  784. 0.7-1ubuntu1
  785. old:
  786. ----------
  787. ID: deliver_knockd-conf
  788. Function: file.managed
  789. Name: /etc/knockd.conf
  790. Result: True
  791. Comment: File /etc/knockd.conf updated
  792. Started: 06:26:06.717147
  793. Duration: 17.544 ms
  794. Changes:
  795. ----------
  796. diff:
  797. ---
  798. +++
  799. @@ -1,15 +1,14 @@
  800. [options]
  801. - UseSyslog
  802. + UseSyslog
  803. [openSSH]
  804. - sequence = 7000,8000,9000
  805. - seq_timeout = 5
  806. - command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  807. - tcpflags = syn
  808. + sequence = tcp:7065,udp:2431,tcp:421,tcp:4113
  809. + seq_timeout = 5
  810. + command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  811. + tcpflags = syn
  812. [closeSSH]
  813. - sequence = 9000,8000,7000
  814. - seq_timeout = 5
  815. - command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  816. - tcpflags = syn
  817. -
  818. + sequence = tcp:4113,tcp:421,udp:2431,tcp:7065
  819. + seq_timeout = 5
  820. + command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
  821. + tcpflags = syn
  822. ----------
  823. ID: prevent_if_ssh_sessions_open
  824. Function: cmd.run
  825. Name: if [ $(/bin/netstat -tnpa | grep "ESTABLISHED.*sshd" | wc -l) -gt 0 ]; then false; fi
  826. Result: True
  827. Comment: Command "if [ $(/bin/netstat -tnpa | grep "ESTABLISHED.*sshd" | wc -l) -gt 0 ]; then false; fi" run
  828. Started: 06:26:06.735404
  829. Duration: 59.527 ms
  830. Changes:
  831. ----------
  832. pid:
  833. 23916
  834. retcode:
  835. 0
  836. stderr:
  837. stdout:
  838. ----------
  839. ID: drop_ssh_port
  840. Function: cmd.run
  841. Name: /sbin/iptables -A INPUT -p tcp --dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}') -j DROP
  842. Result: True
  843. Comment: Command "/sbin/iptables -A INPUT -p tcp --dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}') -j DROP" run
  844. Started: 06:26:06.795619
  845. Duration: 457.367 ms
  846. Changes:
  847. ----------
  848. pid:
  849. 23927
  850. retcode:
  851. 0
  852. stderr:
  853. stdout:
  854. ----------
  855. ID: post-configure_knockd-conf
  856. Function: cmd.run
  857. Name: /bin/sed -i "s/dport 22/dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}')/" /etc/knockd.conf
  858. Result: True
  859. Comment: Command "/bin/sed -i "s/dport 22/dport $(grep -E ^[#P]+ort /etc/ssh/sshd_config | awk '{print $2}')/" /etc/knockd.conf" run
  860. Started: 06:26:07.253529
  861. Duration: 16.545 ms
  862. Changes:
  863. ----------
  864. pid:
  865. 23963
  866. retcode:
  867. 0
  868. stderr:
  869. stdout:
  870. ----------
  871. ID: enable_knockd_service
  872. Function: cmd.run
  873. Name: /bin/systemctl enable knockd.service
  874. Result: True
  875. Comment: Command "/bin/systemctl enable knockd.service" run
  876. Started: 06:26:07.270551
  877. Duration: 539.568 ms
  878. Changes:
  879. ----------
  880. pid:
  881. 23968
  882. retcode:
  883. 0
  884. stderr:
  885. stdout:
  886. ----------
  887. ID: restart_knockd_service
  888. Function: service.running
  889. Name: knockd.service
  890. Result: True
  891. Comment: Started Service knockd.service
  892. Started: 06:26:08.461999
  893. Duration: 168.812 ms
  894. Changes:
  895. ----------
  896. knockd.service:
  897. True
  898. Summary for orjakone
  899. ------------
  900. Succeeded: 8 (changed=7)
  901. Failed: 0
  902. ------------
  903. Total states run: 8
  904. Total run time: 55.125 s
  905. ```
  906. Esimerkkikuva minion-koneen Knock daemonin konfiguraatiotiedostosta, jossa on vaihdettu porttinumero sen mukaan kuin se on määritelty minion-koneen SSH-asetuksissa:
  907. ![minion-knockd-sample](https://raw.githubusercontent.com/Fincer/central-management-of-multiple-servers/master/images/minion-knockd-example.png)