複数のUbuntuサーバーを一括で管理するためのツールとしてLandscapeというものがる。
使い方はさておき、まずはインストールしてみる。
https://landscape.canonical.com/

インストール環境

インストール環境はUbuntu 18.04 Serverを使用

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.1 LTS
Release: 18.04
Codename: bionic

※注意:Webサーバーの設定等を置き換えるので、Landscapeをインストールするサーバーは新規に立てた方が良い
今回は新規サーバーとして構築し、サーバー名/IPアドレスは以下を使う事で進める。

ServerName:vm-uadmin.maple-rice.com
IP Address:192.168.10.22

まずはLandscapeに必要なパッケージをインストールする

使うパッケージは https://help.landscape.canonical.com/ を参照
今回はUbuntu 18.04なので、最新バージョンは18.03になる

$ sudo add-apt-repository -u ppa:landscape/18.03
$ sudo apt-get update
$ sudo apt-get install landscape-server-quickstart

Landscapeが使用するPostgreSQLのユーザーを作成する。

$ sudo -u postgres createuser --createdb --createrole --superuser --pwprompt landscape_superuser

PostgreSQLの各種設定変更

“/etc/postgresql/10/main/pg_hba.conf”の最後の行に以下を追加

host all landscape,landscape_maintenance,landscape_superuser 192.168.10.22/24 md5

“192.168.10.22/24″の部分にはLandscapeがインストールされているサーバーのIPアドレスを指定する。(今回は今構築しているサーバーのIPアドレス)

“/etc/postgresql/10/main/postgresql.conf”の以下を修正する。

listen_addresses = '*'
max_connections = 400
max_prepared_transactions = 400

で、PostgreSQLを再起動

sudo systemctl restart postgresql

ライセンスファイルの登録

今回はフリーライセンスの範囲での利用なのでなにもしない。

RabbitMQの設定

ユーザーの追加など

$ sudo rabbitmqctl add_user landscape <password>
$ sudo rabbitmqctl add_vhost landscape
$ sudo rabbitmqctl set_permissions -p landscape landscape ".*" ".*" ".*"

<password>部分は任意に設定する。

”/etc/rabbitmq/rabbitmq-env.conf”の設定変更
これを有効にする。

NODE_IP_ADDRESS=127.0.0.1

RabbitMQを再起動する。

sudo systemctl restart rabbitmq-server

Landscapeのの設定

"/etc/landscape/service.conf"の設定変更


[stores]
...
host = 192.168.10.22:5432  <--- PostgreSQLサーバーのIPとポート番号(今回は今作成しているサーバー)
...
[broker]
...
user = landscapepassword = <password> <--- RabbitMQの設定で指定したパスワード
...
[schema]
...
store_user = landscape_superuser <--- PostgreSQLを設定したときのスーパーユーザー
store_password = <password> <--- PostgreSQLを設定したときのパスワード

Landscapeのセットアップ

sudo setup-landscape-server

スキーマーのアップグレードの設定
“/etc/default/landscape-server”を変更する。

RUN_ALL="yes" <--- "no"を"yes"に

マルチコアで十分なメモリがある場合は、複数のインスタンスを起動することができるらしい。
その場合は”RUN_XXXX=”の部分を変更すれば良いらしい(今回は変更しない)。

Webサーバー用の証明書の作成

LandscapeはSSLをサポートしているので、自己証明書を作成しておく。
(ここはいろいろやり方があると思いますので、自由に作成する)

秘密鍵の作成

$ sudo openssl genrsa -des3 -out /etc/ssl/private/landscape-server.key 2048 <--- ここでのパスフレーズは適当でOK(削除するので)

パスフレーズの削除

$ sudo openssl rsa -in /etc/ssl/private/landscape-server.key -out /etc/ssl/private/landscape-server.key

証明書(秘密鍵から署名付きの公開鍵)を作成

$ sudo openssl req -new -days 3650 -key /etc/ssl/private/landscape-server.key -out /etc/ssl/private/landscape-server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP <--- "JP"を指定
State or Province Name (full name) [Some-State]:Tokyo <--- "Tokyo"を指定(適当)
Locality Name (eg, city) []: <--- なにも指定しない
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Unknown <--- "Unknown"を指定(適当)
Organizational Unit Name (eg, section) []: <--- なにも指定しない
Common Name (e.g. server FQDN or YOUR name) []:vm-uadmin.maple-rice.com <--- "vm-uadmin.maple-rice.com"を指定
Email Address []: <--- なにも指定しない

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <--- なにも指定しない
An optional company name []: <--- なにも指定しない

証明書(秘密鍵/公開鍵から自己署名)を作成

$ sudo openssl x509 -in /etc/ssl/private/landscape-server.csr -out /etc/ssl/private/landscape-server.crt -req -signkey /etc/ssl/private/landscape-server.key -days 3560

Apacheの設定

サイト設定ファイル”/etc/apache2/sites-available/landscape.conf”を作成する。
ベースは https://help.landscape.canonical.com/LDS/ManualInstallation18.03 から持ってくる

<VirtualHost *:80>

# This Hostname is the HTTP/1.1 hostname that users and Landscape clients will access
# It must be the same as your SSL Certificate's CommonName
# And the DNS Hostname for this machine
# It is not recommended that you use an IP address here...
ServerName @hostname@
ServerAdmin webmaster@@hostname@
ErrorLog /var/log/apache2/landscape.error-log
CustomLog /var/log/apache2/landscape.access-log combined
DocumentRoot /opt/canonical/landscape/canonical/landscape

# Set a Via header in outbound requests to the proxy, so proxied apps can
# know who the actual client is
ProxyVia on
ProxyTimeout 10

<Directory "/">
Options +Indexes
Order deny,allow
Allow from all
Require all granted
Satisfy Any
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 404 /offline/notfound.html
</Directory>

Alias /offline /opt/canonical/landscape/canonical/landscape/offline
Alias /static /opt/canonical/landscape/canonical/static
Alias /repository /var/lib/landscape/landscape-repository


<Location "/repository">
Order deny,allow
Deny from all
ErrorDocument 403 default
ErrorDocument 404 default
</Location>
<LocationMatch "/repository/[^/]+/[^/]+/(dists|pool)/.*">
Allow from all
</LocationMatch>
<Location "/icons">
Order allow,deny
Allow from all
</Location>
<Location "/ping">
Order allow,deny
Allow from all
</Location>

<Location "/message-system">
Order allow,deny
Allow from all 
</Location>

<Location "/static">
Header always append X-Frame-Options SAMEORIGIN
</Location>

<Location "/r">
FileETag none
ExpiresActive on
ExpiresDefault "access plus 10 years"
Header append Cache-Control "public"
</Location>

RewriteEngine On

RewriteRule ^/r/([^/]+)/(.*) /$2

RewriteRule ^/ping$ http://localhost:8070/ping [P]

RewriteCond %{REQUEST_URI} !^/server-status
RewriteCond %{REQUEST_URI} !^/icons
RewriteCond %{REQUEST_URI} !^/static/
RewriteCond %{REQUEST_URI} !^/offline/
RewriteCond %{REQUEST_URI} !^/repository/
RewriteCond %{REQUEST_URI} !^/message-system

# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/(.*) https://@hostname@:443/$1 [R=permanent]
</VirtualHost>

<VirtualHost *:443>
ServerName @hostname@
ServerAdmin webmaster@@hostname@

ErrorLog /var/log/apache2/landscape.error-log
CustomLog /var/log/apache2/landscape.access-log combined

DocumentRoot /opt/canonical/landscape/canonical/landscape

SSLEngine On
SSLCertificateFile @certfile@
SSLCertificateKeyFile @keyfile@
# If you have either an SSLCertificateChainFile or, a self-signed CA signed certificate
# uncomment the line below.
# Note: Some versions of Apache will not accept the SSLCertificateChainFile directive.
# Try using SSLCACertificateFile instead in that case.
# SSLCertificateChainFile /etc/ssl/certs/landscape_server_ca.crt
# Disable to avoid POODLE attack
SSLProtocol all -SSLv3 -SSLv2 -TLSv1
SSLHonorCipherOrder On
SSLCompression Off
SSLCipherSuite EECDH+AESGCM+AES128:EDH+AESGCM+AES128:EECDH+AES128:EDH+AES128:ECDH+AESGCM+AES128:aRSA+AESGCM+AES128:ECDH+AES128:DH+AES128:aRSA+AES128:EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:ECDH+AESGCM:aRSA+AESGCM:ECDH:DH:aRSA:HIGH:!MEDIUM:!aNULL:!NULL:!LOW:!3DES:!DSS:!EXP:!PSK:!SRP:!CAMELLIA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA:!aECDH

# Try to keep this close to the storm timeout. Not less, maybe slightly
# more
ProxyTimeout 305

<Directory "/">
Options -Indexes
Order deny,allow
Allow from all
Require all granted
Satisfy Any
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 404 /offline/notfound.html
</Directory>

<Location "/ajax">
Order allow,deny
Allow from all
</Location>

Alias /offline /opt/canonical/landscape/canonical/landscape/offline
Alias /config /opt/canonical/landscape/apacheroot
Alias /hash-id-databases /var/lib/landscape/hash-id-databases

ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 500 /offline/exception.html
ErrorDocument 502 /offline/unplanned-offline.html
ErrorDocument 503 /offline/unplanned-offline.html
</Proxy>

ProxyPass /robots.txt !
ProxyPass /favicon.ico !
ProxyPass /offline !
ProxyPass /static !

ProxyPreserveHost on


<Location "/r">
FileETag none
ExpiresActive on
ExpiresDefault "access plus 10 years"
Header append Cache-Control "public"
</Location>

<Location "/static">
Header always append X-Frame-Options SAMEORIGIN
</Location>

RewriteEngine On

RewriteRule ^/.*\+\+.* / [F]
RewriteRule ^/r/([^/]+)/(.*) /$2

# See /etc/landscape/service.conf for a description of all the
# Landscape services and the ports they run on.
# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/message-system http://localhost:8090/++vh++https:@hostname@:443/++/ [P,L]

RewriteRule ^/ajax http://localhost:9090/ [P,L]
RewriteRule ^/combo(.*) http://localhost:8080/combo$1 [P,L]
RewriteRule ^/api http://localhost:9080/ [P,L]
RewriteRule ^/attachment/(.*) http://localhost:8090/attachment/$1 [P,L]
RewriteRule ^/upload/(.*) http://localhost:9100/$1 [P,L]

RewriteCond %{REQUEST_URI} !^/robots.txt$
RewriteCond %{REQUEST_URI} !^/favicon.ico$
RewriteCond %{REQUEST_URI} !^/offline/
RewriteCond %{REQUEST_URI} !^/(r/[^/]+/)?static/
RewriteCond %{REQUEST_URI} !^/config/
RewriteCond %{REQUEST_URI} !^/hash-id-databases/

# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/(.*) http://localhost:8080/++vh++https:@hostname@:443/++/$1 [P]

<Location /message-system>
Order allow,deny
Allow from all
</Location>

<Location />
# Insert filter
SetOutputFilter DEFLATE

# Don't compress images or .debs
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|deb)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>

</VirtualHost>

上記ファイルから以下の変更を加える

@hostname@  →  vm-uadmin.maple-rice.com
@certfile@  →  /etc/ssl/private/landscape-server.crt
@keyfile@  →  /etc/ssl/private/landscape-server.key

変更したものがこれ

<VirtualHost *:80>

# This Hostname is the HTTP/1.1 hostname that users and Landscape clients will access
# It must be the same as your SSL Certificate's CommonName
# And the DNS Hostname for this machine
# It is not recommended that you use an IP address here...
ServerName vm-uadmin.maple-rice.com
ServerAdmin webmaster@vm-uadmin.maple-rice.com
ErrorLog /var/log/apache2/landscape.error-log
CustomLog /var/log/apache2/landscape.access-log combined
DocumentRoot /opt/canonical/landscape/canonical/landscape

# Set a Via header in outbound requests to the proxy, so proxied apps can
# know who the actual client is
ProxyVia on
ProxyTimeout 10

<Directory "/">
Options +Indexes
Order deny,allow
Allow from all
Require all granted
Satisfy Any
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 404 /offline/notfound.html
</Directory>

Alias /offline /opt/canonical/landscape/canonical/landscape/offline
Alias /static /opt/canonical/landscape/canonical/static
Alias /repository /var/lib/landscape/landscape-repository


<Location "/repository">
Order deny,allow
Deny from all
ErrorDocument 403 default
ErrorDocument 404 default
</Location>
<LocationMatch "/repository/[^/]+/[^/]+/(dists|pool)/.*">
Allow from all
</LocationMatch>
<Location "/icons">
Order allow,deny
Allow from all
</Location>
<Location "/ping">
Order allow,deny
Allow from all
</Location>

<Location "/message-system">
Order allow,deny
Allow from all 
</Location>

<Location "/static">
Header always append X-Frame-Options SAMEORIGIN
</Location>

<Location "/r">
FileETag none
ExpiresActive on
ExpiresDefault "access plus 10 years"
Header append Cache-Control "public"
</Location>

RewriteEngine On

RewriteRule ^/r/([^/]+)/(.*) /$2

RewriteRule ^/ping$ http://localhost:8070/ping [P]

RewriteCond %{REQUEST_URI} !^/server-status
RewriteCond %{REQUEST_URI} !^/icons
RewriteCond %{REQUEST_URI} !^/static/
RewriteCond %{REQUEST_URI} !^/offline/
RewriteCond %{REQUEST_URI} !^/repository/
RewriteCond %{REQUEST_URI} !^/message-system

# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/(.*) https://vm-uadmin.maple-rice.com:443/$1 [R=permanent]
</VirtualHost>

<VirtualHost *:443>
ServerName vm-uadmin.maple-rice.com
ServerAdmin webmaster@vm-uadmin.maple-rice.com

ErrorLog /var/log/apache2/landscape.error-log
CustomLog /var/log/apache2/landscape.access-log combined

DocumentRoot /opt/canonical/landscape/canonical/landscape

SSLEngine On
SSLCertificateFile /etc/ssl/private/landscape-server.crt
SSLCertificateKeyFile /etc/ssl/private/landscape-server.key
# If you have either an SSLCertificateChainFile or, a self-signed CA signed certificate
# uncomment the line below.
# Note: Some versions of Apache will not accept the SSLCertificateChainFile directive.
# Try using SSLCACertificateFile instead in that case.
# SSLCertificateChainFile /etc/ssl/certs/landscape_server_ca.crt
# Disable to avoid POODLE attack
SSLProtocol all -SSLv3 -SSLv2 -TLSv1
SSLHonorCipherOrder On
SSLCompression Off
SSLCipherSuite EECDH+AESGCM+AES128:EDH+AESGCM+AES128:EECDH+AES128:EDH+AES128:ECDH+AESGCM+AES128:aRSA+AESGCM+AES128:ECDH+AES128:DH+AES128:aRSA+AES128:EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:ECDH+AESGCM:aRSA+AESGCM:ECDH:DH:aRSA:HIGH:!MEDIUM:!aNULL:!NULL:!LOW:!3DES:!DSS:!EXP:!PSK:!SRP:!CAMELLIA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA:!aECDH

# Try to keep this close to the storm timeout. Not less, maybe slightly
# more
ProxyTimeout 305

<Directory "/">
Options -Indexes
Order deny,allow
Allow from all
Require all granted
Satisfy Any
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 404 /offline/notfound.html
</Directory>

<Location "/ajax">
Order allow,deny
Allow from all
</Location>

Alias /offline /opt/canonical/landscape/canonical/landscape/offline
Alias /config /opt/canonical/landscape/apacheroot
Alias /hash-id-databases /var/lib/landscape/hash-id-databases

ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
ErrorDocument 403 /offline/unauthorized.html
ErrorDocument 500 /offline/exception.html
ErrorDocument 502 /offline/unplanned-offline.html
ErrorDocument 503 /offline/unplanned-offline.html
</Proxy>

ProxyPass /robots.txt !
ProxyPass /favicon.ico !
ProxyPass /offline !
ProxyPass /static !

ProxyPreserveHost on


<Location "/r">
FileETag none
ExpiresActive on
ExpiresDefault "access plus 10 years"
Header append Cache-Control "public"
</Location>

<Location "/static">
Header always append X-Frame-Options SAMEORIGIN
</Location>

RewriteEngine On

RewriteRule ^/.*\+\+.* / [F]
RewriteRule ^/r/([^/]+)/(.*) /$2

# See /etc/landscape/service.conf for a description of all the
# Landscape services and the ports they run on.
# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/message-system http://localhost:8090/++vh++https:vm-uadmin.maple-rice.com:443/++/ [P,L]

RewriteRule ^/ajax http://localhost:9090/ [P,L]
RewriteRule ^/combo(.*) http://localhost:8080/combo$1 [P,L]
RewriteRule ^/api http://localhost:9080/ [P,L]
RewriteRule ^/attachment/(.*) http://localhost:8090/attachment/$1 [P,L]
RewriteRule ^/upload/(.*) http://localhost:9100/$1 [P,L]

RewriteCond %{REQUEST_URI} !^/robots.txt$
RewriteCond %{REQUEST_URI} !^/favicon.ico$
RewriteCond %{REQUEST_URI} !^/offline/
RewriteCond %{REQUEST_URI} !^/(r/[^/]+/)?static/
RewriteCond %{REQUEST_URI} !^/config/
RewriteCond %{REQUEST_URI} !^/hash-id-databases/

# Replace the @hostname@ with the DNS hostname for this machine.
# If you change the port number that Apache is providing SSL on, you must change the 
# port number 443 here.
RewriteRule ^/(.*) http://localhost:8080/++vh++https:vm-uadmin.maple-rice.com:443/++/$1 [P]

<Location /message-system>
Order allow,deny
Allow from all
</Location>

<Location />
# Insert filter
SetOutputFilter DEFLATE

# Don't compress images or .debs
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|deb)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>

</VirtualHost>

Apacheのモジュールを有効にする

rewrite, proxy_http, ssl, headers, expires, の各モジュールを有効にする。

$ sudo a2enmod rewrite proxy_http ssl headers expires

デフォルト定義を無効にして、Landscape用の定義を有効にする。

$ sudo a2dissite 000-default
$ sudo a2ensite landscape.conf
$ sudo /etc/init.d/apache2 restart

Landscape サービスの再起動

以下のコマンドでLandscapeを再起動する。

$ sudo lsctl restart

これでインストールは完了。ブラウザからインストールしたサーバー(”https://vm-uadmin.maple-rice.com/”)へアクセスすればファーストユーザー設定画面が開く。

Webを開くとファーストユーザー設定が面になるので、ユーザー名、E-mail Address、パスワードを設定する。
以降、ログインする場合はここで登録したE-mail Addressとパスワードを使用する。

登録が完了するとダッシュボード画面が表示されます。
まだ、管理対象のサーバーを登録していないので、左上の”0 computers registerd”となっています。

管理対象側(クライアント)サーバーの設定

まず、landscape-clientをインストールします。

$ sudo apt update
$ sudo apt install landscape-client

先ほどサーバー側で作成した証明書””をクライアントPCに登録します。

証明書をコピー

$ sudo mv landscape-server.crt /etc/landscape/

証明書を設定ファイル”/etc/landscape/client.conf”に登録します。

ssl_public_key = /etc/landscape/landscape-server.crt

クライアントを登録するためのコマンドはサーバーのWeb画面左上に”followinf these instructions”と書かれたリンクがあるのでそれをクリック。

すると画面の中央付近の”Register the computer”の部分に登録するコマンドが記載されているので、それを参考に登録すればOK。

今回は”vm-nucfs”というコンピューターを登録してみます。
注意:証明書を指定しないと接続できないので、”–ssl-public-key /etc/landscape/landscape-server.crt”を追加します。

$ sudo landscape-config --computer-title "vm-nucfs" --account-name standalone --url https://vm-uadmin.maple-rice.com/messa
ge-system --ping-url http://vm-uadmin.maple-rice.com/ping --ssl-public-key /etc/landscape/landscape-server.crt

This script will interactively set up the Landscape client. It will
ask you a few questions about this computer and your Landscape
account, and will submit that information to the Landscape server.
After this computer is registered it will need to be approved by an
account administrator on the pending computers page.

Please see https://landscape.canonical.com for more information.


A registration key may be associated with your Landscape
account to prevent unauthorized registration attempts. This
is not your personal login password. It is optional, and unless
explicitly set on the server, it may be skipped here.

If you don't remember the registration key you can find it
at https://landscape.canonical.com/account/standalone

Account registration key:

The Landscape client communicates with the server over HTTP and
HTTPS. If your network requires you to use a proxy to access HTTP
and/or HTTPS web sites, please provide the address of these
proxies now. If you don't use a proxy, leave these fields empty.

HTTP proxy URL:
HTTPS proxy URL:

Landscape has a feature which enables administrators to run
arbitrary scripts on machines under their control. By default this
feature is disabled in the client, disallowing any arbitrary script
execution. If enabled, the set of users that scripts may run as is
also configurable.

Enable script execution? [y/N]:

You may provide an access group for this computer e.g. webservers.

Access group:

You may provide tags for this computer e.g. server,precise.

Tags:
[ ok ] Restarting landscape-client (via systemctl): landscape-client.service.
Please wait...

Request a new registration for this computer now? [Y/n]: Y
System successfully registered.

特別に何かを入力する必要はない。”System successfully registerd.”が表示されれば正常に登録要求が飛んでいるので、サーバーのダッシュボード右上の通知部分に”1 pending computer nees authorization”というメッセージが表示されます。

メッセージをクリックすると登録画面になりますので、コンピューター名の横のチェックを入れて”Accept”ボタンを押すとコンピューターが登録されます。

その後、元のダッシュボード画面に戻ると、左上の表示が”1 computer registered”となり、正常に登録が完了します。

管理の方法については別途。