tag:crieit.net,2005:https://crieit.net/tags/vsftpd/feed 「vsftpd」の記事 - Crieit Crieitでタグ「vsftpd」に投稿された最近の記事 2020-12-24T00:29:36+09:00 https://crieit.net/tags/vsftpd/feed tag:crieit.net,2005:PublicArticle/16416 2020-12-24T00:28:56+09:00 2020-12-24T00:29:36+09:00 https://crieit.net/posts/ansible-remove-user-and-settings-of-vsftpd-apache-20201224 vsftpd と Apache の設定を削除しLinuxユーザも削除する <p>以前取り上げた<a href="https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202">Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする</a>の逆方向バージョンです。</p> <p>つまり、</p> <ul> <li>Linuxユーザを削除</li> <li>上記ユーザを vsftpdユーザ からも削除</li> <li>Apache の仮想サイトの設定と該当ディレクトリのデータを全て削除</li> </ul> <p>を行うタスクを作ろう、と考えました。</p> <p>これは、上記のプレイブックを一時的なテスト環境として作った後、削除することも往々にしてあり、手動で削除するのが面倒になってきたからです。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>テストに利用するサーバは前の記事と同じサーバで、該当プレイブックによって vsftpd や Apache が設定されている、という状況を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ │ ├ entrypoint.sh │ └ ansible/ │ ├ (諸々元のプレイブックと同じ構造) │ ├ main.yml // Ansible の設定用 playbook │ └ resset.yml // 今回追加した削除用タスク │ ├ docker-compose.yml └ Dockerfile </code></pre> <p>ほぼ前の記事の通り、というか同じプロジェクトをそのまま流用しています。元々の意図が設定用プレイブックに対して設定を元に戻すためのものなので、同じ場所にあった方が都合は良いと考えました。</p> <p>ただ、リセットするためのタスクは設定用タスクほど複雑ではないのでタスクを分割せずに1つのファイルに既述することにしました。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>上記ディレクトリ構造より、設定用のプレイブックに使用する変数ファイルがあるため、これをそのまま流用します。</p> <h3 id="ansible/resset.yml"><a href="#ansible%2Fresset.yml">ansible/resset.yml</a></h3> <pre><code class="yml">- name: Remove vsftpd and httpd settings become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Remove user user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent remove: yes - name: Remove user in vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "" - name: Remove user_conf file file: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes - name: Remove Apache virtual site data file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: absent - name: Remove Apache conffile file: path: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" state: absent - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>今回のメイン。削除用のタスクです。</p> <p>やっていることは冒頭で記した通り。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <h3 id="削除用プレイブックを走らせる前"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B%E5%89%8D">削除用プレイブックを走らせる前</a></h3> <pre><code class="bash"># less /etc/passwd ## 略 USERNAME:x: </code></pre> <p>設定用プレイブックで追加されたユーザがいることを確認。</p> <pre><code class="bash"># less /etc/vsftpd/user_list ## 略 # BEGIN ANSIBLE basic setup: USERNAME USERNAME # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 4 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 23 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. -rw-rw-r-- 1 ADMIN_USER ADMIN_USER 107 MM月 DD hh:ii USERNAME # less /etc/vsftpd/user_conf/USERNAME # BEGIN ANSIBLE basic setup: USERNAME local_root=/var/www/sample_site # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 5 ADMIN_USER ADMIN_USER 51 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html drwxr-xr-x 3 ADMIN_USER ADMIN_USER 17 MM月 DD hh:ii sample_site # ls -al /etc/httpd/conf.d/ 合計 36 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 137 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 439 MM月 DD hh:ii sample_site.conf # less /etc/httpd/conf.d/sample_site.conf <VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/sample_site/web" ServerName www.sample_site.jp ServerAlias sample_site.jp ScriptAlias /cgi-bin/ /var/www/sample_site/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^sample_site\.jp$ RewriteRule ^(.*)$ http://www.sample_site.jp$1 [R=301,L] <Directory "/var/www/sample_site/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>Apache 側にも仮想サイトの設定があり、仮想サイト用のディレクトリが切られていることを確認。</p> <p>FTPでログインしたり、 <code>hosts</code> で名前解決して仮想サイトにアクセスできることを確認。</p> <p>一通りプレイブックの設定通りです。</p> <h3 id="削除用プレイブックを走らせる"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B">削除用プレイブックを走らせる</a></h3> <h4 id="Dry run"><a href="#Dry+run">Dry run</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K --check BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>まずは Dry run でエラーが出ないことを確認。大丈夫そうです。</p> <h4 id="本番"><a href="#%E6%9C%AC%E7%95%AA">本番</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>続いて本番実行。完了しました。</p> <h3 id="削除用プレイブックを走らせた後"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%81%9F%E5%BE%8C">削除用プレイブックを走らせた後</a></h3> <p>それでは、念のため確認していきたいと思います。</p> <pre><code class="bash"># less /etc/passwd </code></pre> <p>設定したユーザが消えていることを確認。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 0 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. # less /etc/vsftpd/user_list ## 略 nobody </code></pre> <p>vsftpd の設定も消えています。OK。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 4 ADMIN_USER ADMIN_USER 33 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html # ls -al /etc/httpd/conf.d/ 合計 32 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 114 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf </code></pre> <p>仮想サイトのディレクトリは丸ごと消えて、設定ファイルも消えました。OKです。</p> <p>当然、FTPでログインできなくなっていますし、ブラウザでアクセスすると仮想サイトが消えたので代理の仮想サイトが応答してきました。OKです。</p> <hr /> <p>以上より、一通り意図通りの動作になったことを確認できました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="ユーザ削除"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E5%89%8A%E9%99%A4">ユーザ削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/KeijiYONEDA/items/011b78b12022202d4ea1">【Ansible】開発者ユーザー追加・削除のベスト・プラクティスを考える - Qiita</a></li> </ul> <h4 id="ファイル削除"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%89%8A%E9%99%A4">ファイル削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tekunabe.hatenablog.jp/entry/2019/03/03/ansible_file_intro#-%E4%BE%8B2-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%84%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B">[Ansible] file モジュールの基本的な使い方(ファイルやディレクトリの操作) - てくなべ (tekunabe)</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/waterada/items/4e64cc6f810a92001c95">ansible のモジュール(ファイル操作等)をまとめてみました - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.greptips.com/posts/1269/">Ansibleのfileモジュールでディレクトリをabsentするのは危険 - grep Tips *</a></li> </ul> <h4 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tech.smartcamp.co.jp/entry/2019/05/10/215035">Ansible Playbookでユーザ管理(登録・削除)をまるっとやる - SMARTCAMP Engineer Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/volanja/items/54a7dbc75b909e89d8fc">Ansibleの新モジュール replace(置換)を使ってみた。 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://uuutee.net/ansible/howto-replacing-text-with-ansible/">Ansibleでテキスト置換を行ういくつかの方法 | uuutee.log</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://akishin.hatenablog.jp/entry/20130817/1376709924">Ansible で複数行の文字列置換 - akishin999の日記</a></li> </ul> <h3 id="Linuxコマンド"><a href="#Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">Linuxコマンド</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://eng-entrance.com/linux-command-userdel">userdelコマンドについて詳しくまとめました 【Linuxコマンド集】</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16255 2020-12-04T00:13:51+09:00 2020-12-04T00:13:51+09:00 https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202 Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする <p>Ansible を使って設定を行う例として、 Linuxユーザを作成してFTPユーザとし、 Apache の仮想サイトを作成する部分をやってみたいと思います。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>対象サーバの LAMP は<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/07/09/centos7-wordpress-move/">CentOS7.5 + Apache + PHP + MySQL サーバを構築し、WordPressサイトを引っ越す(2018/11/20)</a>のうち</p> <ul> <li>1.初期設定 ~ 4.リポジトリ追加</li> <li>5.vsftpd のうち <ul> <li>5.1.インストール, 5.2.設定</li> </ul></li> <li>6.Apache ~ 11.Webmin</li> <li>12.Apache仮想サイトのうち <ul> <li>12.1.ダミーサイトの作成</li> </ul></li> <li>16.SSH</li> </ul> <p>が既に設定済みの状態のサーバとします(13.Let’s Encrypt ~ 15.WP-CLI は対象外)。</p> <p>また、今回 Ansible で設定するのは</p> <ul> <li>5.vsftpd のうち <ul> <li>5.3.ユーザ設定</li> <li>5.4.ユーザ作成・設定</li> </ul></li> <li>12.Apache仮想サイトのうち <ul> <li>12.2. 仮想サイト作成</li> </ul></li> </ul> <p>の部分を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ // データ永続化領域 │ ├ entrypoint.sh // Dockerコンテナ起動時に実行するシェルスクリプト │ └ ansible/ // Ansible 用ディレクトリ │ ├ targets/ // リモートホストの情報を収めるディレクトリ │ │ └ hosts // リモートサーバの一覧 (今回は1つのみ) │ │ │ ├ tasks/ // Ansible のタスクを収めるディレクトリ │ │ ├ add_user.yml // Linuxユーザの作成 │ │ ├ vsftpd_user_settings.yml // vsftpd の設定 │ │ └ apache_settings.yml // Apache 仮想サイトの設定 │ │ │ ├ templates/ // Apache 仮想サイト設定のテンプレートを収めるディレクトリ │ │ └ vhost.conf.j2 // Apache 仮想サイト設定のテンプレート │ │ │ ├ vars/ // 各種パラメータ変数の設定を収めるディレクトリ │ │ └ param_vars.yml // 各種パラメータ変数 │ │ │ └ main.yml // Ansible の playbook │ ├ docker-compose.yml // Docker Compose 設定ファイル └ Dockerfile // Dockerfile </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/10/22/build_docker_container_as_ansible_controller/">Ansibleコントロールノード を Dockerコンテナ でビルドし、リモートサーバに公開鍵認証でSSH接続してインストール済みのパッケージの一覧を取得するまで</a>や<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a>の記事の構造をベースにカスタマイズ。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/philotic_moby_test/tree/yum_update">arm-band/philotic_moby_test at yum_update</a></li> </ul> <p>一揃いを Github に置きました。</p> <h3 id="Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts"><a href="#Dockerfile%2C+docker-compose.yml%2C+entrypoint.sh.+ansible%2Ftargets%2Fhosts">Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts</a></h3> <p>この辺りはそのまま。 <code>ansible/targets/hosts</code> はグループ名を変更していますが、対となる <code>ansible/main.yml</code> の <code>hosts</code> の指定を変えれば良いだけなので些事。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yaml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>まずは今回の新顔の変数から。当初は末尾の「備考1: コマンドライン引数を変数に代入する」のように引数でコマンドラインから直接渡すことを考えていましたが、上記の通り6つもあるとそれだけでコマンドが長くなってしまい可読性が下がるので最終的に止めました。</p> <p>代わりに変数を1つのファイルにまとめて、コマンド自体の長さは変わらないように調整しました。</p> <p>この場合、以下の <code>ansible/main.yml</code> で触れますが <code>vars_files: ./vars/param_vars.yml</code> という一行で変数ファイルの読み込みができ、かつそれ以降は <code>vars</code> キーで変数としてそのまま使用できるので導入はわりとすんなり行きました。</p> <h3 id="ansible/main.yml"><a href="#ansible%2Fmain.yml">ansible/main.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd and httpd become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Add Linux User include_tasks: ./tasks/add_user.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" passwd: "<span>{</span><span>{</span> password <span>}</span><span>}</span>" - name: Settings vsftpd user_list and user_conf include_tasks: ./tasks/vsftpd_user_settings.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Setup Apache conffile include_tasks: ./tasks/apache_settings.yml vars: directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" url: "<span>{</span><span>{</span> domain <span>}</span><span>}</span>" ip: "<span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>" portnumber: "<span>{</span><span>{</span> portnum <span>}</span><span>}</span>" </code></pre> <p>タスクのメイン部分。基本は前回と同様で、 <code>tasks</code> で指定する各種タスクが置き換わった形です。変数については上記の通り。</p> <h3 id="ansible/tasks/add_user.yml"><a href="#ansible%2Ftasks%2Fadd_user.yml">ansible/tasks/add_user.yml</a></h3> <pre><code class="yaml">- name: Add user, setting password and groups user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" password: "<span>{</span><span>{</span> password | password_hash('sha512') <span>}</span><span>}</span>" groups: apache append: yes </code></pre> <p><code>ansible/main.yml</code> から渡ってきた各変数が使用される(ここでは <code>username</code>, <code>password</code>)、という形です。</p> <p>一点注意なのはパスワードはそのままだと平文で保存されてしまいますが、実際に認証する際はハッシュ値に変換されるので不一致となってしまいます。そこで、<strong>保存時にハッシュ値に変換</strong>するように <code>password_hash('sha512')</code> を噛ませています。</p> <h3 id="ansible/tasks/vsftpd_user_settings.yml"><a href="#ansible%2Ftasks%2Fvsftpd_user_settings.yml">ansible/tasks/vsftpd_user_settings.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" - name: Settings vsftpd user_conf blockinfile: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "local_root=/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes </code></pre> <p>次は vsftpd の設定。 <code>user_list</code> にユーザとして登録し、 <code>user_conf</code> ディレクトリの下にユーザ名のファイルを作成、そこに <code>local_root</code> の指定を記述する、という内容です。</p> <p>ここでも一点注意。</p> <p>設定ファイルへの書き込みとして <code>blockinfile</code> を使用しているのですが、 <strong><code>marker</code> の値がユニークでない</strong>と、 <code>loop</code> で繰り返し処理をしたり、今回のケースだと異なる仮想サイトの設定を行ったり(Ansible を2回実行する)した場合に<strong>後勝ちで上書きされてしまう</strong>こと。</p> <p>今回のケースでは <code>user_list</code> に2回目の変数のユーザしか残らなくなってしまいます。そのため、 <strong><code>marker</code> の最後にユーザ名を混ぜることでコメント文が実行の度にユニークとなる</strong>ようにしました。</p> <h3 id="ansible/tasks/apache_settings.yml"><a href="#ansible%2Ftasks%2Fapache_settings.yml">ansible/tasks/apache_settings.yml</a></h3> <pre><code class="yaml">- name: mkdir root file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: directory owner: ADMIN_USER group: ADMIN_USER mode: 0755 recurse: no - name: mkdir web file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" state: directory owner: apache group: apache mode: 0775 recurse: no - name: Setup Apache conffile template: src: ../templates/vhost.conf.j2 dest: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" mode: '0644' - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>続いて Apache 仮想サイトの設定。ディレクトリを作ったり権限・所有者設定したり。</p> <p>最後の <code>Setup Apache conffile</code> の処理では jinja2 のテンプレートから仮想サイト用の conf ファイルを作成しています。</p> <h3 id="ansible/templates/vhost.conf.j2"><a href="#ansible%2Ftemplates%2Fvhost.conf.j2">ansible/templates/vhost.conf.j2</a></h3> <pre><code class="jinja2"><VirtualHost <span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>:<span>{</span><span>{</span> portnum <span>}</span><span>}</span>> DocumentRoot "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" ServerName <span>{</span><span>{</span> domain <span>}</span><span>}</span> {% if domain | regex_search("^www\.", ignorecase=True) %} ServerAlias <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '\\1') <span>}</span><span>}</span> {% endif %} ScriptAlias /cgi-bin/ /var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web/cgi-bin/ {% if domain | regex_search("^www\.", ignorecase=True) %} RewriteEngine on RewriteCond %{HTTP_HOST} <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '^\\1$') | regex_replace("\.", '\.') <span>}</span><span>}</span> RewriteRule ^(.*)$ http://<span>{</span><span>{</span> domain <span>}</span><span>}</span>$1 [R=301,L] {% endif %} <Directory "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>大体設定ファイルの内容ですが、各種変数を使用しています。</p> <p>また、ドメイン(変数 <code>domain</code> )が <code>www.</code> 始まりの場合はサーバ名を <code>www.example.jp</code> のように <code>www.</code> 付きとし、同時に <code>ServerAlias</code> で <code>example.jp</code> と <code>www.</code> なしもフォローするような条件分岐(<code>if</code>, <code>regex_search</code>)を挟みました。</p> <p>併せて、 <code>www.</code> なしのURLにアクセスした場合に <code>www.</code> ありにリダイレクトする設定も、変数 <code>domain</code> を正規表現置換(<code>regex_replace</code>)で一括で入れるようにしました。</p> <p>例えば、 <code>domain: www.example.jp</code> とした場合は以下のような設定ファイルが作成されます。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/example/web" ServerName www.example.jp ServerAlias example.jp ScriptAlias /cgi-bin/ /var/www/example/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^example\.jp$ RewriteRule ^(.*)$ http://www.example.jp$1 [R=301,L] <Directory "/var/www/example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>一方、 <code>domain: form.example.jp</code> のようなケースだと以下。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/form_example/web" ServerName form.example.jp ScriptAlias /cgi-bin/ /var/www/form_example/web/cgi-bin/ <Directory "/var/www/form_example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>上記の通り、 <code>ServerAlias</code> と <code>Rewrite</code> 系がありません。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <p>以上のような構成で動作検証。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Settings vsftpd and httpd] ********************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Add Linux User] *********************************************************************************************included: /workspace/ansible/tasks/add_user.yml for 192.0.2.1 TASK [Add user, setting password and groups] **********************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_list and user_conf] ********************************************************************included: /workspace/ansible/tasks/vsftpd_user_settings.yml for 192.0.2.1 TASK [Settings vsftpd user_list] **********************************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_conf] **********************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************included: /workspace/ansible/tasks/apache_settings.yml for 192.0.2.1 TASK [mkdir root] *************************************************************************************************changed: [192.0.2.1] TASK [mkdir web] **************************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=12 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>OKです。</p> <p>仮想サイトにアクセスして Apache のデフォルトページが表示される、FTPでログインできる、ファイルアップロードなどの操作ができる、といった動作を一通りできることを確認できました。</p> <h3 id="備考1: コマンドライン引数を変数に代入する"><a href="#%E5%82%99%E8%80%831%3A+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%BC%95%E6%95%B0%E3%82%92%E5%A4%89%E6%95%B0%E3%81%AB%E4%BB%A3%E5%85%A5%E3%81%99%E3%82%8B">備考1: コマンドライン引数を変数に代入する</a></h3> <p>例えば、以下のような <code>main.yml</code> を用意します。</p> <pre><code class="yaml">- name: Get packages from hosts and do yum update become: yes become_user: ADMIN_USER become_method: su hosts: - update_servers tasks: - name: Get packages from hosts before update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts before update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> before <span>}</span><span>}</span>" - name: Do yum update include_tasks: ./tasks/yum_update.yml - name: Get packages from hosts after update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts after update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> after <span>}</span><span>}</span>" </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a> の <code>main.yml</code> のうち、 <code>vars</code> の部分を少し編集したものです。</p> <p>これで以下のように playbook を実行。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K -e &quot;before=before2 after=after22&quot; </code></pre> <p>すると、 <code>workspace/192.0.2.1_packages_before2</code> と <code>workspace/192.0.2.1_packages_after22</code> が生成され、コマンドラインの引数が変数として使用されたことが分かりました。</p> <p>当初はこれの延長線を考えていましたが、冒頭の通り6つも引数があると長くなってしまうので最終的には不採用としました。</p> <p>ただし、これはこれで引数の使い方として参考になりそうなのでメモとして残しておきます。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="引数、変数"><a href="#%E5%BC%95%E6%95%B0%E3%80%81%E5%A4%89%E6%95%B0">引数、変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YumaInaura/items/6e05d87858bd647d11ab">ansible コマンドでモジュール引数 ( パラメータ ) を複数渡す方法 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/modules_intro.html">モジュールの概要 - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_variables.html">変数の使用 - Ansible Documentation</a></li> </ul> <h4 id="変数"><a href="#%E5%A4%89%E6%95%B0">変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/c_u/items/e91ca023fbb124fec34a">Ansible: vars_files を使用した loop処理 - Qiita</a></li> </ul> <p><code>vars_files</code> を採用。</p> <h4 id="ユーザ作成"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E4%BD%9C%E6%88%90">ユーザ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=156">Ansibleでユーザ追加 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> </ul> <h4 id="パスワード"><a href="#%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89">パスワード</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=967">Ansibleでユーザパスワード設定 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sicksixrock66/items/474068167de9c8454319">適当にansibleでrootパスワードを変えようとしたらアクセスできなくなった件 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/263760">Linux - Ansibleでパスワード変更の際に、パスワードポリシーを遵守させたい|teratail</a></li> </ul> <h4 id="Facts"><a href="#Facts">Facts</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://nwengblog.com/ansible-facts/">Ansible:Factsについて(Ansible 2.9.6) | matsublog</a></li> </ul> <h4 id="設定に追記"><a href="#%E8%A8%AD%E5%AE%9A%E3%81%AB%E8%BF%BD%E8%A8%98">設定に追記</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YuukiMiyoshi/items/f1b773f65792ce0e9101">【Ansible】そのCopy、Blockinfileの方が良いかも? - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/nakacya/items/a624f6710c3ca0edc8a9">Ansible Blockinfile の tips - Qiita</a></li> </ul> <h4 id="blockfile"><a href="#blockfile">blockfile</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dekitakotono.blogspot.com/2019/05/blockinfile.html">blockinfile モジュール-φ(.. ) のメモ</a></li> </ul> <blockquote> <p>複数のテキストブロックを追加する場合、マーカーラインをユニークにしないとテキストブロックが上書きされる</p> </blockquote> <p><code>marker</code> の文字列はユニークになるようにすること。</p> <h4 id="systemd"><a href="#systemd">systemd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tnamao.hatenablog.com/entry/2016/12/03/014742">ansible で systemd 配下のサービスを扱う - 日記</a></li> <li><a target="_blank" rel="nofollow noopener" href="http://pj-doaa.hatenablog.com/entry/2017/09/05/120849">AnsibleのModule:systemd - ときどきAnsible日記</a></li> </ul> <h4 id="ディレクトリ作成"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E4%BD%9C%E6%88%90">ディレクトリ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/hnakamur/items/b5a17d8cb289432014d5">[Ansible] ディレクトリが無かったら作成する - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://blog.adachin.me/archives/2781">[ansible]ディレクトリ作成はfileモジュールで! ? ADACHIN SERVER LABO</a></li> </ul> <h4 id="httpd"><a href="#httpd">httpd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/articles/tutorial-ansible-with-role/">Role を使ったAnsibleのチュートリアル | Developers.IO</a></li> </ul> <h4 id="jinja2, if"><a href="#jinja2%2C+if">jinja2, if</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yteraoka/items/7119d4e1e2f8faddfb64">Ansible の Template 機能の紹介 - Qiita</a></li> </ul> <h4 id="jinja2, regrex"><a href="#jinja2%2C+regrex">jinja2, regrex</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html">Using filters to manipulate data - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/30413616/using-regex-in-jinja-2-for-ansible-playbooks">python - using regex in jinja 2 for ansible playbooks - Stack Overflow</a></li> </ul> <h3 id="usermod"><a href="#usermod">usermod</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.atmarkit.co.jp/ait/articles/1612/14/news022.html">【 usermod 】コマンド――ユーザーアカウントの情報を変更する:Linux基本コマンドTips(73) - @IT</a></li> </ul> arm-band