- 投稿日:2020-02-25T23:30:47+09:00
tblsでデータベースのスキーマ情報をマークダウンで出力する
概要
DBのスキーマ情報をドキュメント化したいと思ったので使用したツールをメモします。
使用方法
tblsのgithubを参考。
dockerイメージの入手
$ docker pull k1low/tbls:latest
1コマンドでデータベースをドキュメント化できる手軽さ。
$ tbls doc postgres://dbuser:dbpass@hostname:5432/dbname
dockerでやる場合は以下です。
$ docker run --rm -v $PWD:/work k1low/tbls doc postgres://dbuser:dbpass@hostname:5432/dbname筆者の場合は、mysqlなので、以下です。
$ docker run --rm -v $PWD:/work k1low/tbls doc mysql://dbuser:dbpass@hostname:3306/dbname
- 投稿日:2020-02-25T23:14:25+09:00
dockerコンテナ内からホストのmysqlにアクセスする
概要
こちらの記事でWindowsホストのdockerコンテナ上にpython環境を構築しました。
dockerコンテナからホストのmysqlにアクセスした時のメモです。
環境
python 3.8.1 mysqlの設定ファイル書き換え
my.cnf内のbind-addressをコメントアウトする。
[mysqld] # bind-address = 127.0.0.1mysqlにユーザー追加
> grant all privileges on [db_name].* to [user_name]@"[ip_address]" identified by '[password]' with grant option; > select user,host from mysql.user; > FLUSH PRIVILEGES;pythonコード
mysql_demo.pyimport mysql.connector as mydb conn = mydb.connect( host='(ホストのIPアドレス)', port='3306', user='admin', password='password', database='sample_db' ) conn.ping(reconnect=True) print(conn.is_connected()) cur = conn.cursor() cur.execute("SELECT * FROM sample_table;") cur.close conn.close rows = cur.fetchall() for row in rows: print(row)参考
- 投稿日:2020-02-25T23:10:13+09:00
【Docker】チュートリアル(Python+php)
はじめに
Dockerを勉強するにあたり、素晴らしいチュートリアル動画があったのでそれを元に自分で手を動かして見ました。リンク先の動画は英語ですので、日本語で少し補足をしながら進めていきます。初心者のため認識の誤りがあるかもしれませんので、その際はコメント頂けると幸いです。
事前にdocker、docker-composeのインストールが必要です。
元動画
productディレクトリにはjsonを返すAPIをpythonで用意します。
websiteディレクトリには画面を描画するphpを用意します。product
まずはdocker_tutorial配下にproductディレクトリを作成します。
$ mkdir productそしてシンプルなPythonコードを作成します。flaskとflask_restfulというライブラリを使用します。
api.pyfrom flask import Flask from flask_restful import Resource, Api app = Flask(__name__) api = Api(app) class Product(Resource): def get(self): return{ 'products': [ 'Ice cream', 'Chocolate', 'Fruit' ] } api.add_resource(Product, '/') if __name__ == '__main__': app.run(host='0.0.0.0', port=80, debug=True)ローカル環境にpythonをインストールしている場合は、pip installなどでライブラリをインストールしますが、Dockerを使用した場合は個別にインストールする必要はありません。その代わりにコンテナ起動時に必要となるライブラリなどを以下のテキストファイルに記載するか、後述のDockerfile内にpip installのコマンドを記載します。バージョンはライブラリの公式サイトなどを参照して使用したいバージョンを記載します。
requirements.txtFlask==0.12 flask-restful==0.3.5次にDockerfileを作成します。
DockerfileはDocker上で動作させるコンテナの構成情報を記述するためのファイルです。FROM python:3-onbuild COPY . /usr/src/app CMD ["python", "api.py"]FROM
FROMにはベースとするDockerイメージを指定します。また「onbuild」を記載することで、Dockerfile を使って docker build をするとき、Dockerfile 内で pip install を書かなくても Dockerfile と同じディレクトリに requirements.txt があると自動的にインストールをするようになっています。COPY
COPYにはローカルファイルをDockerイメージのどこにコピーするかを記載します。今回の場合はproductディレクトリをDocker上の/usr/src/app内にコピーします。CMD
CMDにはコンテナ起動時に実行するコマンドを記載します。次にdocker-compose.ymlを作成します。docker-composeには
- Dockerイメージをビルドするための情報(使用するDockerfile、イメージ名など)
- コンテナ起動するための情報(ホストとの共有ディレクトリ設定やポートフォワードなどの起動オプションなど)
- 使用するDockerネットワーク
などを記載します。
docker-compose.ymlversion: '3' services: product-service: build: ./product volumes: - ./product:/usr/src/app ports: - 5001:80version
docker-composeで使用するバージョンを記載します。現在はバージョン3が最新ですので、3を指定します。services
アプリケーションを動かすための各要素をServiceと読んでいます。各サービスをネストしてこちらに記載します。今回の場合は「product-service」というサービスを起動します。build
指定したディレクトリにあるDockerfileでコンテナを起動します。今回の場合はproductディレクトリのDockerfileでコンテナを起動します。volumes
ローカリのディレクトをコンテナのディレクトにマウントします。今回の場合はproductディレクトリをコンテナ上の/usr/src/appディレクトリにマウントします。ports
Dockerを立ち上げるポート番号を記載します。今回は5001番ポートで立ち上げます。それではDockerを起動
$ docker-compose up起動が完了したら、localhost:5001にアクセスします。
以下のような画面が表示されたら問題なく起動しています。
ここまでで、簡単にPython、Flaskの環境ができることが分かります。この状態でapi.pyを以下のように変更し、保存します。
api.pyclass Product(Resource): def get(self): return{ 'products': [ 'Ice cream', 'Chocolate', 'Fruit', 'Eggs' ] }再読み込みを行うと、表示内容も更新されます。コンテナを再起動しなくてもマウントしてくれます。
ここまできたらコンソール上で「control+C」を押して、dockerを一旦停止します。
website
次はdocker_tutorial配下にwebsiteというディレクトリを作成します。こちらにはphpのファイルを作成します。
http://product-serviceの結果をループして表示する処理です。
ここでいうproduct-serviceはdocker-composeに記載したサービス名が該当します。index.php<html> <head> <title>My Shop</title> </head> <body> <h1>Welcome to my shop</h1> <ul> <?php $json = file_get_contents('http://product-service'); $obj = json_decode($json); $products = $obj->products; foreach($products as $product) { echo "<li>$product</li>"; } ?> </ul> </body>次にdocker-compose.ymlを以下のように変更します。
docker-compose.ymlversion: '3' services: product-service: build: ./product volumes: - ./product:/usr/src/app ports: - 5001:80 website: image: php:apache volumes: - ./website:/var/www/html ports: - 5000:80 depends_on: - product-servicewebsite
servicesにwebsiteというサービスを追加します。image
imageを記載することで、Docker Hub上に用意されている既存のイメージを使用することができます。buildとimageは同時に指定することはできません。depends_on
サービス同士の依存関係を記載します。今回の場合、websiteが実行されるより前にproduct-serviceが実行されるようになります。docker-compose.ymlにproduct-serviceがない場合はエラーになります。再度Dockerを起動します。
$ docker-compose up起動が完了したらlocalhost:5000にアクセスします。
以下のような画面が表示されていれば成功です。さいごに
Dockerを使用することで、簡単にPython+phpの環境を作ることができました。私もDocker初心者のためこれからも引き続き学習していきたいと思います。
おまけ
-dをつけることでバックグラウンドでコンテナを立ち上げることができます。
$ docker-compose up -d Starting docker_tutorial_product-service_1 ... done Starting docker_tutorial_website_1 ... donepsコマンドで起動中のコンテナの一覧が確認できます。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 24de043f94d9 php:apache "docker-php-entrypoi…" 10 minutes ago Up About a minute 0.0.0.0:5000->80/tcp docker_tutorial_website_1 da62924c1154 docker_tutorial_product-service "python api.py" 32 minutes ago Up About a minute 0.0.0.0:5001->80/tcp docker_tutorial_product-service_1stopでコンテナを停止することができます。
$ docker-compose stop Stopping docker_tutorial_website_1 ... done Stopping docker_tutorial_product-service_1 ... done $ docker ps ONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES参考
- 投稿日:2020-02-25T22:55:59+09:00
windowsにdockerでpython環境を用意する
概要
筆者はwindowsマシンを使用しています。
pythonの実行環境を用意するにあたり、
ホストがwindows、mac、linuxとコロコロ変わるので、環境構築の手軽さや、
ホストを汚したくなかった事もありdockerを使うことにしました。環境
windows10 pro
Hyper-Vの機能を使用出来る必要があるようです。docker for windowsインストール
以下を参考にさせて頂きインストール
https://ops.jig-saw.com/tech-cate/docker-for-windows-install設定ファイル記述
Dockerfile
DockerfileFROM python:3 USER root RUN apt-get update RUN apt-get -y install locales && \ localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 ENV LANG ja_JP.UTF-8 ENV LANGUAGE ja_JP:ja ENV LC_ALL ja_JP.UTF-8 ENV TZ JST-9 ENV TERM xterm RUN apt-get install -y vim less RUN pip install --upgrade pip RUN pip install --upgrade setuptoolsdocker-compose.yml
docker-compose.ymlversion: '3' services: python3: restart: always build: . container_name: 'python3' working_dir: '/root/' tty: true volumes: - ./tmp:/root/tmp extra_hosts: - "(ホストのCOMPUTERNAME):(ホストのIPアドレス)" ports: - 3306:3306
volumes
ホストのパスをコンテナにマウントします。
extra_hosts
ホスト名のマッピングを追加します。
コンテナの/etc/hosts
に以下と記載されます。162.242.195.82 somehost 50.31.209.229 otherhost
ports
(ホスト側ポート):(コンテナ側ポート)
ビルド
Dockerfile含むビルド方法
> docker-compose up -d --buildコンテナ停止
> docker-compose down参考
- 投稿日:2020-02-25T20:06:06+09:00
【Docker】Unhandled exception: Drive has not been shared
$ docker-compose up -dで「Unhandled exception: Drive has not been shared」エラーが発生した場合、以下の設定を変更することで解消します。
setting→Resources→FILE SHARING→Cドライブにチェック
画面キャプチャはDocker Desktop for windowsです。
- 投稿日:2020-02-25T18:59:25+09:00
Laravel on Dockerでのブロードキャスト
TL;DL
Docker環境のLaravelでのブロードキャストを実装しました
Dockerを使ったLaravel環境構築
インストールするのはLaravel 6.xです。
$ mkdir broadcast $ cd broadcast $ composer create-project --prefer-dist laravel/laravel src├── docker-compose.yml ├── docker │ ├── echoserver │ │ └── Dockerfile │ ├── nginx │ │ └── default.conf │ ├── php │ │ ├── Dockerfile │ │ ├── cmd.sh │ │ └── php.ini │ └── redis │ └── data ├── logs └── src # Laravelの置き場所docker-compose.ymlversion: '3' services: web: image: nginx:1.17.8-alpine ports: - 80 volumes: - ./src:/var/www:cached - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf - ./logs/nginx:/var/log/nginx:cached depends_on: - php environment: VIRTUAL_HOST: localhost php: image: broadcast-php build: ./docker/php volumes: - ./src:/var/www:cached - ./logs/php:/var/log/php - ./docker/php/cmd.sh:/usr/local/bin/cmd.sh nodejs: image: node:13.8-alpine volumes: - ./src:/work:cached working_dir: /work echo-server: image: broadcast-echo-server build: ./docker/echoserver ports: - "6001:6001" command: laravel-echo-server start volumes: - ./src:/work:cached working_dir: /work redis: image: redis:latest ports: - "6379:6379" volumes: - "./docker/redis/data:/data"docker/echoserver/DockerfileFROM node:13.8-alpine # timezone RUN apk add --update --no-cache --virtual build-dependencies tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ echo "Asia/Tokyo" > /etc/timezone && \ apk del build-dependencies RUN npm install -g laravel-echo-server WORKDIR /work CMD ["laravel-echo-server", "start"]docker/php/DockerfileFROM php:7.3-fpm-alpine COPY php.ini /usr/local/etc/php/ # lib RUN apk add --no-cache --virtual build-dependencies gcc make autoconf libc-dev libtool \ && apk add --no-cache --virtual zlib1g-dev libxml2-dev # composer COPY --from=composer /usr/bin/composer /usr/bin/composer # php extension RUN docker-php-ext-install xml pdo_mysql # timezone RUN apk add --update --no-cache --virtual build-dependencies tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ echo "Asia/Tokyo" > /etc/timezone && \ apk del build-dependencies WORKDIR /var/wwwdocker/php/cmd.sh#!/bin/sh php-fpm
docker/nginx/default.confserver { listen 80; index index.php index.html; root /var/www/public; charset utf-8; location / { root /var/www/public; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param HOGE $realip_remote_port; } }ビルドして、最初の
docker-compose up -d
ではLaravel Echo Serverは起動しません。$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES nginx:1.17.8-alpine "nginx -g 'daemon of…" 14 seconds ago Up 12 seconds 0.0.0.0:32774->80/tcp broadcast_web_1 broadcast-php "docker-php-entrypoi…" 16 seconds ago Up 13 seconds 9000/tcp broadcast_php_1 node:13.8-alpine "docker-entrypoint.s…" 16 seconds ago Exited (0) 13 seconds ago broadcast_nodejs_1 broadcast-echo-server "docker-entrypoint.s…" 16 seconds ago Exited (0) 12 seconds ago broadcast_echo-server_1 redis:latest "docker-entrypoint.s…" 16 seconds ago Up 13 seconds 0.0.0.0:6379->6379/tcp broadcast_redis_1そこで初期化コマンドを実行する必要があります。
$ docker-compose run --rm echo-server laravel-echo-server init ? Do you want to run this server in development mode? Yes ? Which port would you like to serve from? 6001 ? Which database would you like to use to store presence channel members? redis ? Enter the host of your Laravel authentication server. http://localhost ? Will you be serving on http or https? http ? Do you want to generate a client ID/Key for HTTP API? No ? Do you want to setup cross domain access to the API? No ? What do you want this config to be saved as? laravel-echo-server.json Configuration file saved. Run laravel-echo-server start to run server.これで
src/laravel-echo-server.json
という設定ファイルが作られます。
この中のRedisの接続情報でRedisコンテナを指定します。src/laravel-echo-server.json{ ... "databaseConfig": { "redis": { "host": "redis", "port": 6379 }, "sqlite": { "databasePath": "/database/laravel-echo-server.sqlite" } }, ... }落として、再度立ち上げます。
$ docker-compose down $ docker-compose up -d $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES nginx:1.17.8-alpine "nginx -g 'daemon of…" 10 seconds ago Up 7 seconds 0.0.0.0:32775->80/tcp broadcast_web_1 node:13.8-alpine "docker-entrypoint.s…" 11 seconds ago Exited (0) 9 seconds ago broadcast_nodejs_1 broadcast-php "docker-php-entrypoi…" 11 seconds ago Up 9 seconds 9000/tcp broadcast_php_1 broadcast-echo-server "docker-entrypoint.s…" 11 seconds ago Up 9 seconds 0.0.0.0:6001->6001/tcp broadcast_echo-server_1 redis:latest "docker-entrypoint.s…" 11 seconds ago Up 9 seconds 0.0.0.0:6379->6379/tcp broadcast_redis_1これでLaravel Echo Serverも起動しました。
にアクセスするとLaravelインストール直後の画面が表示されます。
ブロードキャスト
ここからが本題のブロードキャストです。
以下が公式のドキュメント。https://laravel.com/docs/6.x/broadcasting
https://readouble.com/laravel/6.x/ja/broadcasting.html今回はRedisを使います。
ほぼほぼ公式の手順でうまくいきます(そして公式ドキュメントに載っていない設定で躓く。。)
App\Providers\BroadcastServiceProvider
の登録コメントを外します。
$ diff src/config/app.php.orig src/config/app.php 174c174 < // App\Providers\BroadcastServiceProvider::class, --- > App\Providers\BroadcastServiceProvider::class,HTMLへのCSRFトークンの追加とJSの読み込み
$ diff src/resources/views/welcome.blade.php.orig src/resources/views/welcome.blade.php 8a9,10 > <meta name="csrf-token" content="{{ csrf_token() }}"> > 98a101,102 > > <script src="{{ mix('js/app.js') }}"></script>Redisのクライアントライブラリのインストール
$ cd src $ composer require predis/predisイベントの作成
$ docker-compose exec php php artisan make:event HelloWorldEvent Event created successfully.イベントの
broadcastOn()
でチャンネルを返すのですが、今回作るのは認証が必要ないチャンネルとします。src/app/Events/HelloWorldEvent.php<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class HelloWorldEvent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $message = 'Hello World!!'; /** * Create a new event instance. * * @return void */ public function __construct() { // } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new Channel('hello-world-channel'); } }イベント発行のコマンドの作成
$ docker-compose exec php php artisan make:command BroadcastHelloWorld Console command created successfully.src/app/Console/Commands/BroadcastHelloWorld.php<?php namespace App\Console\Commands; use Illuminate\Console\Command; use App\Events\HelloWorldEvent; class BroadcastHelloWorld extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'command:broadcast-hello-world'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { event(new HelloWorldEvent()); } }フロントエンド
laravel-echo
とsocket.io-client
が必要です。$ docker-compose run --rm nodejs npm install $ docker-compose run --rm nodejs npm install --save laravel-echo socket.io-clientなんか
npm install
で警告いっぱい出た。。。
チャンネルとイベントを指定してリッスンします。$ diff src/resources/js/app.js.orig src/resources/js/app.js 1a2,14 > > import Echo from 'laravel-echo'; > > window.io = require('socket.io-client'); > > window.Echo = new Echo({ > broadcaster: 'socket.io', > host: window.location.hostname + ':6001' > }); > > window.Echo.channel('hello-world-channel').listen('HelloWorldEvent', e => { > console.log(e.message); > });.envの変更
$ diff src/.env.orig src/.env 16c16 < BROADCAST_DRIVER=log --- > BROADCAST_DRIVER=redis 18c18 < QUEUE_CONNECTION=sync --- > QUEUE_CONNECTION=redis 22c22,24 < REDIS_HOST=127.0.0.1 --- > REDIS_HOST=redis > REDIS_CLIENT=predis > REDIS_PREFIX=""!!重要!!
ここでRedisのprefix
を空文字にすることが重要です。
これが公式ドキュメントに書かれていなくて、調べてやっと見つけました。ブロードキャストできるか確認
$ docker-compose run --rm nodejs npm run dev$ docker-compose exec php php artisan command:broadcast-hello-world $ docker-compose exec php php artisan queue:work --stop-when-empty Processing: App\Events\HelloWorldEvent Processed: App\Events\HelloWorldEvent成功しました!!
laravel-echo-server.json
のRedisコンテナ指定の修正や、Redisのprefix
の変更など、Redis周りで難しかったですが、なんとかDocker環境でブロードキャストできました参考URL
この記事がなかったら自分は諦めてました。感謝
- 投稿日:2020-02-25T13:05:10+09:00
【Docker】docker-compose up -d 時のエラー No container found for ○○ の対処法
- 投稿日:2020-02-25T12:13:43+09:00
docker-machineのデフォルトOS,shellを確認してみました
結果
ディストリビューション:Core linux
シェル:bash
ディストリビューションはコアリナックスというミニマムなものでした。
core linuxシェルは有名なbashでした。
状況
docker-machineで立ち上げた時linuxっぽいものが
動いているけどディストリビューションは何だろう?
という疑問が出てきたので確認してみました。以下docker、docker-machineが動く前提です。
確認した手順|コマンド
Verification.sh#verificationという名前の仮想マシンを作る $ docker-machine create verification #verificationにsshで入る $ docker-machine ssh verification #ここからはverification内でのコマンド実行 #ディストリビューションを確認するコマンド実行 $ cat /etc/issue Core Linux #シェルを確認 $ echo $SHELL /bin/bash備考
ディストリビューション(正確にはlinuxの系列)や
シェルの違いでコマンドが違ってくるので自分用備忘録として書きました。
- 投稿日:2020-02-25T09:57:29+09:00
WSL2+docker+PHPのWindows開発環境構築(1) WSL2編
本記事はWindows Insider Previewを使っています。
ご利用は計画的にヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 余談はここから ↓-------------------
関連記事
* Bash on Ubuntu on Windowsを使う(1)
* Bash on Ubuntu on Windowsを使う(2):初期設定
* Bash on Ubuntu on Windowsを使う(3):WindowsからLinuxを使う
* WSL2+docker+PHPのWindows開発環境構築(1) WSL2編
* WSL2+docker+PHPのWindows開発環境構築(2) docker編仕事でdockerを使う機会が増えた。
なぜか知らんがMacを使わされるので大変面倒くさい。
(どこが便利なんだ?これ。)現在の仕事はPCを持ち込みができるらしいので、
この際Windows上で開発環境を作ろうと思う。数年前に登場したWSLというものがあって、
それについて記事も書いているが、
順調に進化してこのたびver2となる。
(リリースは令和2年5月頃)
そのときを見据えて今からPreview版を使って環境を作ってみよう。注意
- Preview版がStableになっても記事を書き換えたりしないのでご注意を。
- 記事が長くなったのでdocker編は別記事で。
------------------- ↓ 本題はここから ↓-------------------
事前準備
・Windows Update
前提としてWindowsを最新にしておく。
(https://www.microsoft.com/ja-jp/software-download/windows10
(執筆時November Update 2019)・WSLを有効にする
PowerShellを管理者モードで起動
1. 「スタート」「Windows PowerShell」「Windows PowerShell」を右クリック
2. 「管理者として実行」
以下のコマンドを実行
PS> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart PS> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /noresttそしてPCを再起動! (ここ重要)
Windows Insider Previewをインストール
・Previewプログラムに参加
- Windows Preview Programに参加
- Windows Insider の設定で「開始する」を押下
- 「アカウントリンク」より自身のアカウントと紐付ける
- 「スロー」を選択
- 「再起動」
- 「設定」「更新とセキュリティ」「更新プログラムのチェック」を押下
- すべてのインストール完了後「再起動」
- (「Windows 10、バージョン????の機能更新プログラム」がインストールされるまで6,7を繰り返す)
・バージョンの確認
「コマンドプロンプト(またはPowerShell)」で以下のコマンドを実行
$ ver Microsoft Windows [Version 10.0.19041.84]数字が10.0.18917以上なら成功
WSL2のインストール
*デフォルト設定をWSL2にする
wslコマンドのデフォルト設定をWSL2になるようにしておく。
前置きが長くなったがここからが本番。C:¥> wsl --set-default-version 2・Linuxを取得
windows Storeで好きなLinux Distributionをダウンロードしておく
ここではベタなUbuntuを選択。
https://www.microsoft.com/ja-jp/p/ubuntu/9nblggh4msv6
(私はPengwin派)状態確認
C:¥> wsl -l -v NAME STATE VERSION * Ubuntu Stopped 2あとは普通にUbuntuを使うだけ。
C:¥> wsl $ cat /etc/os-release NAME="Ubuntu" VERSION= 〜〜〜〜〜〜さて、次はdockerだ。
------------------- ↓ 後書はここから ↓-------------------
WSL1からWSL2に変換する
すでにに手持ちのLinuxを使っていて、
WSL2に変えたいときがあるだろう。
変換する手段はあるので慌てずに。状態の確認
C:¥> wsl -l -v NAME STATE VERSION * WLinux Stopped 1 Ubuntu Stopped 2WSL2に変換
C:¥> wsl --set-version WLinux 2 変換中です。この処理は数分かかることがあります...もう一度状態を確認してみる。
C:¥> wsl -l -v NAME STATE VERSION * WLinux Stopped 2 Ubuntu Stopped 2WSL2のリセット方法
「アプリと機能」のアプリの詳細から「リセット」するのが定番だったけど、
コマンド一つでできるようになるみたい。C:¥> wsl --unregister ubuntuコマンドの後、「スタート」からLinuxを起動すると初期状態になっている。
ターミナルをWindows Terminalに変える
個人的におすすめしたいターミナルがWindows Termminal。
https://www.microsoft.com/ja-jp/p/windows-terminal-preview/9n0dx20hk701
タブ機能が標準で付いている。powerline対応フォントを入れる
powerlineというPython製のシェルがあるのだが、
それに対応したフォントがある。
https://github.com/powerline/fonts
install.ps1シェルをpowershellで走らせるとフォントがインストールされる
- 投稿日:2020-02-25T08:23:23+09:00
Dockerコンテナだけで完結するフロントエンド環境を構築するぞ!( VSCode Remote Development )
この記事は何?
Introducing Remote Development for @code ???️
— Visual Studio Code (@code) May 2, 2019
A new set of extensions that enable you to open any folder in a container, on a remote machine, or in the Windows Subsystem for Linux (WSL) and take advantage of VS Code's full feature set. #remote
? https://t.co/ChYGQ89Y5fVSCodeの拡張機能であるRemote Developmentを使えば、Dockerコンテナ内のソースコードを直接書き換えることができます。
これを使えば、わざわざホスト側のソースコードを書き換えてVolumeを使って、変更をコンテナ内部にマウントするなんてことをしなくて済みます。この記事では、この拡張を使ってDockerコンテナ内だけで完結するフロントエンド( React + Webpack + TypeScript )の環境構築を行います。
詳しい解説や使い方は、以下の素晴らしい記事を参照ください。
Dockerで立ち上げた開発環境をVS Codeで開く!
VS Code Remote Development で Docker 開発環境を利用する
Visual Studio CodeのRemote DevelopmentとDockerで快適な開発環境をゲット環境構築
Docker Imageの作成
作業がしやすいように、Dockerfileを定義して、自分好みの環境を作っておきます。こちらは、各自でカスタマイズして使いやすくしてください。もし
DockerHub
などに既にイメージがある場合は、こちらの工程は不要です。Dockerfile# こちらのイメージには node と npm と yarn が入っています FROM node:lts-alpine # git と curl をインストール # alpine版は apt-get ではなく、apkを使います RUN apk update && apk add --virtual=module curl git WORKDIR /usr/src/app
Dockerfile
が出来たら、それを元にイメージを作成します。$> docker build -t <任意のイメージ名前> <DockerfileのあるPATH>example$> docker build -t frontend .
- -t : イメージの名前を設定します。イメージ名には大文字はダメみたいです。
処理が完了したら、ちゃんと作成されているか確認してみましょう。
例では、frontend
という名前で作成しました。$> docker images REPOSITORY TAG IMAGE ID CREATED SIZE frontend latest dfcs99e now 106MB node lts-alpine 927s12c now 88.1MB
ちゃんと作成されていますね。それでは次に行きましょう。
Docker Volumesの作成
volumesを作成します。理由は、volumesを設定しておかないとデータの永続化で出来ないので、誤ってDockerコンテナを削除してしまうと、作業内容が消えてしまいます。なので、volumesを作ってそこにデータを入れて永続化します。
volumesは、dockerが管理するものと任意のフォルダーに管理する方法がありますが、この記事ではdockerが管理する方法をとっています。
$> docker volume create <任意の名前>
example$> docker volume create ReactAppVolume
こちらもちゃんと作成できているか、確認してみましょう
$> docker volume ls DRIVER VOLUME NAME local ReactAppVolume例では、
ReactAppVolume
という名前で作成しましたが、ちゃんと作成されていますね。
それでは次に行きましょう。Docker Containerの作成
実際に作業するコンテナを作成します。こちらのコンテナは基本的には
docker rm
などはしないようしましょう。volumesを設定してあるので、消しても大丈夫だとは思いますが。。。$> docker run -d --name <任意の名前> -v <作成したVolume名>:<マウントしたいPATH> <イメージ名> sleep infinityexample$> docker run -d --name SampleReactApp -v ReactAppVolume:/usr/src/app frontend sleep infinity
- -d : バックグランドで実行
- -v : 設定されたPATHに
volumes
を設定します- --name : dockerコンテナに任意の名前を付けれます
- sleep infinity : コンテナが起動したときに実行するコマンド。( これをやらないとすぐにコンテナが落ちてしまうため )
※ 本来であれば
-p
オプションでポート開放する必要があると思いますが、指定しなくても筆者の環境では動いたので、書いていません。
もし一通りやって、http://locahost:8080
にアクセスしても404 Not Found
が出た場合は、-p 8080:8080
を追加してください。すでにVolumeがある場合
こちらは、間違ってコンテナを削除してしまった時や、コンテナを複製したい場合に使います。
$> docker run -d --name <任意のコンテナ名> --mount source=<Volume名>,target=<マウントしたいPATH> <イメージ名> sleep infinityexample$> docker run -d --name SampleReactApp --mount source=ReactAppVolume,target=/usr/src/app frontend sleep infinity
- --mount : volumeの内容を、指定した
target
のPATHにマウントします作成したコンテナをVSCodeで開く
コンテナが停止してないとちゃんと動かないことがあったので、停止しておきましょう。
※ コンテナが停止していても、Remote Developmentがちゃんと検知してくれますし、開くときに勝手に起動してくれますので、大丈夫です。$> docker stop <作成したコンテナ名> or <コンテナID>
example$> docker stop SampleReactApp
コンテナが停止出来たら、次はVSCodeを開きます。この時Remote Developmentがインストール済みである事を想定しています。インストールをしていない人は、インストールしましょう。
※「 ワークスペースに有効にする 」だと正常に動作しないので、ちゃんと全体にインストールしましょう
そうするとアイコンが追加されて、それをクリックするとDockerコンテナ一覧が表示される画面が表示されます。
その画面が表示されたら、コンテナをVSCodeで開くアイコンがあるので、それをクリックするとコンテナをVSCodeで開くことができます。
今回の例では、
イメージ名 : frontend
・コンテナ名 : SampleReactApp
としていますので、frontend(SampleReactApp)
の項目を開きます。DockerコンテナをVSCodeで開けたら後は、環境構築していくだけです。
React + Webpack + TypeScriptの環境構築
※この節のコマンドの実行は、全てDockerコンテナ内で行っています。また、この記事ではyarnを使っています。
まずは、
package.json
の作成です。package.jsonを生成/usr/src/app# yarn init yarn init v1.22.0 question name (app): question version (1.0.0): question description: question entry point (index.js): question repository url: question author: question license (MIT): question private: success Saved package.json生成された
package.json
に、npm scrips
を定義してましょう。package.json{ "name": "app", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "start": "set NODE_ENV=development & webpack-dev-server", "build": "set NODE_ENV=production & webpack" } }
yarn start
とコマンドを打てば、サーバが立ち上がってReact
の実行結果を確認することができます。
yarn build
とコマンドを打つと、dist
フォルダーにビルドファイルが出力されます。※まだこの段階では、コマンドを実行してもエラーになります。
次に、必要なモジュールのインストールを行います。
buildに必要なモジュールをインストール/usr/src/app# yarn add -D webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin typescript ts-loader @types/react @types/react-dom
- -D :
--save-dev
の略。package.jsonにdevDependencies
のモジュールとして書かれます。- webpack・webpack-cli :
React
をビルドするのに必要なBundler。- webpack-dev-server :
React
の表示内容を確認するためのサーバーを立ててくれます。- html-webpack-plugin :
webpack
で、HTMLも出力してくれるプラグイン。- clean-webpack-plugin : 古いビルドファイルを削除してくれるプラグイン。
- typescript :
javascript
に型を無理くり付けた言語- ts-loader :
webpack
でtypescript
をコンパイルするのに使います。- @types/react・@types/react-dom :
typescript
でreact
書くのに必要な型定義ファイル次は、
React
のインストールreactをインストール/usr/src/app# yarn add react react-dom次に
webpack.config.js
を定義します。こちらは必要最低限の構成になっています。webpack.config.jsconst path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const mode = process.env.NODE_ENV === "production" ? "production" : "development"; const isDev = process.env.NODE_ENV === "development"; const outputPath = path.resolve("src/index.tsx"); module.exports = { entry: outputPath, mode, devtool: isDev ? "source-map" : "none", target: "web", output: { path: path.resolve(__dirname, "dist"), publicPath: "/", filename: isDev ? "bundle.[hash].js" : "bundle.js" }, resolve: { extensions: [".js", ".ts", ".tsx"], }, module: { rules: [ { test: /\.(ts|tsx)$/, use: "ts-loader" } ] }, devServer: { contentBase: outputPath, historyApiFallback: true, port: 8080, hot: true, host:"0.0.0.0" }, plugins: [ new HtmlWebpackPlugin({ title: "SampleReactApp" }), new CleanWebpackPlugin(), ] };次は、
typescript
のコンパイル設定ファイルを定義。こちらは、結構適当です。tsconfig.json{ "compilerOptions": { "outDir": "./dist/", "sourceMap": true, // mapファイル出力してー "module": "ESNext", // importを使えるようにしてー "noImplicitAny": true, // 定義無しだと勝手にAny?ダメだ!ゆ゛る゛さ゛ん゛! "target": "es5", // ES5にコンパイルしてー "jsx": "react", // react使うよー "strict": true, // strictモード使うよー "moduleResolution": "node", // node_modulesを使えるようにするよー "lib": [ "dom", // 多分、必須 "es2019" // 好きなesのバージョンでいいんじゃない?しらんけど。 ] }, "include": [ "./src/**/*.ts", "./src/**/*.tsx" ], "exclude": [ "node_modules" ] }設定ファイルが書き終わったら、次は
React
のソースコードを書いてきます。src/index.tsximport * as React from "react" import { render } from "react-dom" const App : React.SFC = () => ( <div className="app"> <h1>Hello React!</h1> </div> ) const root = document.createElement("div") root.id = "root" document.body.appendChild(root) render(<App />, root)WebpackDevServerを立ち上げる
ここまで出来たら、
yarn start
を実行するとサーバーが立ち上がるので、http://localhost:8080
にアクセスすると、Hello React!と書かれたページが表示されていると思います。サーバーを起動/usr/src/app# yarn start yarn run v1.22.0 $ webpack-dev-server ℹ 「wds」: Project is running at http://0.0.0.0:8080/ ℹ 「wds」: webpack output is served from / ℹ 「wds」: Content not from webpack is served from /usr/src/app/src/index.tsx ℹ 「wds」: 404s will fallback to /index.html ℹ 「wdm」: Hash: 31e9b9d394452c9a83d5 Version: webpack 4.41.6 Time: 2499ms Built at: 2020-02-25 5:03:20 Asset Size Chunks Chunk Names bundle.js 1.41 MiB main [emitted] main index.html 186 bytes [emitted] Entrypoint main = bundle.js ...これで終わりです!お疲れさまでした。
- 投稿日:2020-02-25T08:18:50+09:00
squidでActiveDirectory連携とSSLインターセプトするProxyをdockerで手軽につくる
概要
squidによるProxyサーバで、こんなことがやりたい。
- ActiveDirectoryのセキュリティグループを利用して、アクセスログにユーザ名を残したい。
- セキュリティグループ毎に別のアクセス制限をかけたい。
- アップデートサイトなどはホワイトリストにして、NTLMのSSOを回避して無認証で通したい。
- SSLインターセプトして、HTTPSでもFQDN以降のフルパスでアクセス制限したい。
アクセス条件は次のとおり
ユーザ種別 ホワイトリスト イントラサイト 特例サイト 一般サイト ブラックリスト システムユーザ 〇 × × × × 通常ユーザ 〇 〇 × × × 一部許可ユーザ 〇 〇 〇 × × 全許可ユーザ 〇 〇 〇 〇 × 検証環境
機器など
- CentOS8(8.1.1911)
- squid(4.4)
- Windows Servr 2019
- Docker(19.03.5)
その他のパラメータ
以降の作業内容では、以下のパラメータにあわせて説明をしています。
カスタマイズする場合には、適宜修正をしてください。ドメイン名
ADドメイン名:prosper2.net
NetBIOSドメイン名:PROSPER2LDAPグループ検索用ユーザ
dn: CN=searchuser,CN=Users,DC=prosper2,DC=net
sAMAccountName: searchuser
userPrincipalName: searchuser@prosper2.net
パスワード:s3arch#PWDSSLを終端するためのCA証明書
秘密鍵ファイル名:icaprivkey.pem
証明書ファイル名:icacert.pem
X509v3基本制限(critical): CA
X509v3鍵使用法(critical): Digital Signature, Certificate Sign, CRL SignDocker環境
Dockerコンテナ
コンテナ名:proxy-ad
ホスト名:proxy-ad
ポートバインド:8081:8081/tcpDockerネットワーク
IPv6:有効
サブネット:fd5a:ceb9:ed8d:a::/64
ネットワーク名:br_proxy_nw作業内容
事前準備
ADユーザの準備
以下のユーザを作成しておく。
squid検索ユーザ以外は、既存のユーザにセキュリティグループを割り当ててもOK
ユーザ種別 ユーザ名 OU セキュリティグループ 通常ユーザ josys.saburo employee - 一部許可ユーザ jinji.jiro employee ProxyLimit 全許可ユーザ soumu.taro employee ProxyUnlimit squid検索ユーザ searchuser - - なお、検索用ユーザはLDAPでアクセスするだけなので、対話ログインができないようにポリシーで制御しておいたほうがよいでしょう。
searchuserのパスワードは
s3arch#PWD
として説明します。証明書の準備
参考エントリ
ActiveDirectory証明機関(ADCS)から中間CAを生成する
OpenSSLでプライベート認証局の構築(ルートCA、中間CA)SSLインターセプトのため、中間CAでSSLを終端しています。
参考エントリは自身の環境の例で説明していますが、中間CAの機能を有していればどのような方法で取得しても問題ありません。
ブラウザでアクセスするクライアント側には、生成した中間CAの上位となるCAの証明書をインストールしておきます。dockerネットワークのIPv6化
参考エントリ
dockerネットワークのipv6対応方法と通信経路の整理squidがIPv6で自分自身にアクセスするため、dockerもIPv6にする必要があります。
dockerコンテナ
docker-compose.yml
でまとめてしまいたかったのですが、compose v3は、IPv6指定ができないので、ネットワーク作成は手動です。構成ファイルの準備
ファイル構成
# tree ./ --charset=C ./ |-- docker-compose.yml `-- proxy-ad |-- Dockerfile |-- blacklist |-- docker-entrypoint.sh |-- icacert.pem |-- icaprivkey.pem |-- intralist |-- permlist |-- rsyslog.conf |-- smb.conf |-- squid.conf |-- squid_log `-- whitelistDockerfile
docker-compose.ymlversion: '3' services: proxy-ad: build: ./proxy-ad image: infraserv:proxy-ad container_name: proxy-ad hostname: proxy-ad restart: always networks: br_proxy_nw: ports: - 8081:8081 cap_add: - SYS_ADMIN security_opt: - seccomp:unconfined volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro environment: TZ: 'Asia/Tokyo' networks: br_proxy_nw: external: trueproxy-ad/DockerfileFROM centos:centos8 RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ; \ dnf -y update ; dnf -y install epel-release rsyslog logrotate cronie ; \ rm -f /etc/logrotate.d/syslog ; \ dnf -y install squid samba samba-winbind openldap-clients authselect samba-winbind-clients ; \ mkdir /etc/squid/certs ;\ systemctl enable squid COPY squid.conf /etc/squid COPY icacert.pem /etc/squid/certs COPY icaprivkey.pem /etc/squid/certs COPY squid_log /etc/logrotate.d COPY blacklist /etc/squid COPY whitelist /etc/squid COPY permlist /etc/squid COPY intralist /etc/squid COPY rsyslog.conf /etc COPY smb.conf /etc/samba COPY docker-entrypoint.sh /usr/local/bin/ RUN mkdir /var/local/squid ;\ /usr/lib64/squid/security_file_certgen -c -s /var/local/squid/ssl_db -M 4MB ;\ chown -R squid.squid /var/local/squid ;\ ln -s usr/local/bin/docker-entrypoint.sh / ENTRYPOINT ["docker-entrypoint.sh"] CMD [ "/usr/sbin/init" ]
docker-entrypoint.sh
はヘルパースクリプトとして実行権限を与える必要があります。
以下ファイルを作成したら、chmod 755 docker-entrypoint.sh
で権限付与してください。proxy-ad/docker-entrypoint.sh#!/bin/sh if [ ! -e /etc/systemd/system/multi-user.target.wants/smb.service ] ; then authselect select winbind --force net ads join -U searchuser%s3arch#PWD systemctl enable smb systemctl enable winbind systemctl start smb systemctl start winbind fi exec "$@"samba
ドメイン名などは適宜修正してください。
proxy-ad/smb.conf[global] workgroup = PROSPER2 server string = proxy-ad security = ads hosts allow = 127. realm = PROSPER2.NETsquid
proxy-ad/squid.conf# ------------------------------------------------------ # authentication helpers # ------------------------------------------------------ # NTLM authentication helper : ActiveDirectory SSO # max processes : 5 auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp auth_param ntlm children 5 # LDAP search helper : check ActiveDirectory Security Group # -v 3 : use LDAP version 3 # -P : persistent LDAP connection # -R : do not follow referrals # -S : Strip Domain name # -b : Base DN (search group) # -D -w : bind DN (search user) and password # -h : LDAP server (AD DS) # -f : filter %u:User %g:Gourp # %LOGIN : SSO login user external_acl_type security_group %LOGIN /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "ou=employee,dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 -f '(&(objectclass=person)(sAMAccountName=%u)(memberOf=CN=%g,ou=employee,dc=prosper2,dc=net))' external_acl_type ou_check %LOGIN /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "ou=employee,dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 -f '(&(objectclass=person)(sAMAccountName=%u))' acl gr_unlimit external security_group ProxyUnlimit acl gr_limit external security_group ProxyLimit acl gr_employee external ou_check employee # ------------------------------------------------------ # original rules # ------------------------------------------------------ acl manager proto cache_object acl localhost src localhost acl localhost src 127.0.0.1/32 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https #acl Safe_ports port 70 # gopher #acl Safe_ports port 210 # wais #acl Safe_ports port 1025-65535 # unregistered ports #acl Safe_ports port 280 # http-mgmt #acl Safe_ports port 488 # gss-http #acl Safe_ports port 591 # filemaker #acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT # Allow cache http_access allow localhost manager http_access deny manager # Deny not Safe_ports http_access deny !Safe_ports # Deny CONNECT request on not SSL_ports http_access deny CONNECT !SSL_ports # ------------------------------------------------------ # user rules # ------------------------------------------------------ # Deny Blacklist sites acl blacklist url_regex -i "/etc/squid/blacklist" http_access deny blacklist # Allow Whitelist sites acl whitelist url_regex -i "/etc/squid/whitelist" http_access allow whitelist # Deny not Domain User http_access deny !gr_unlimit !gr_limit !gr_employee # permit : ProxyUnlimit http_access allow gr_unlimit # permit : ProxyLimit and permlist acl permlist url_regex -i "/etc/squid/permlist" http_access allow gr_limit permlist # permit : No security gourp and intralist acl intralist url_regex -i "/etc/squid/intralist" http_access allow gr_employee intralist # deny : default http_access deny all # ------------------------------------------------------ # SSL BUMP exeption whitelist # ------------------------------------------------------ http_port 8081 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/certs/icacert.pem key=/etc/squid/certs/icaprivkey.pem sslcrtd_program /usr/lib64/squid/security_file_certgen -s /var/local/squid/ssl_db -M 4MB sslcrtd_children 5 ssl_bump bump !whitelist sslproxy_cert_error allow intralist sslproxy_cert_error deny all # ------------------------------------------------------ # default options # ------------------------------------------------------ visible_hostname proxy-ad coredump_dir /var/spool/squid refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320URLフィルタのリスト
ブラックリストは空のファイルでも大丈夫です。
後述する動作確認の際のリストと同一です。proxy-ad/blacklistqiita.com/bashawayホワイトリストはひとまずwindowsとcentos(yum)の対応としています。
後述する動作確認の際のリストと同一です。proxy-ad/whitelistmicrosoft.com www.msftconnecttest.com onecs-live.azureedge.net windowsupdate.com google.com google-analytics.com fedoraproject.org centos.org ftp.nara.wide.ad.jp ftp.jaist.ac.jp ftp.riken.jp ftp.iij.ad.jp ftp.tsukuba.wide.ad.jp mirror.fairway.ne.jp ftp.yz.yamagata-u.ac.jp ftp-srv2.kddilabs.jp yum.mariadb.org一部許可リストはブラックリストとの比較のため、これにしています。
後述する動作確認の際のリストと同一です。proxy-ad/permlistqiita.comイントラ用リストも通信確認のため、以下をサンプルにしていますが、ADのドメインとあわせておくとよいでしょう。
proxy-ad/intralistugtop.comsyslog
syslogという名前で引けるサーバにむけて514/udpでsyslogを投げます。
対象はaccess.log
cache.log
の2種類です。proxy-ad/rsyslog.confmodule(load="imfile") input(type="imfile" file="/var/log/squid/access.log" tag="pseudolog_squid_access_log" facility="local0" severity="notice") :syslogtag, isequal, "pseudolog_squid_access_log" @syslog:514 input(type="imfile" file="/var/log/squid/cache.log" tag="pseudolog_squid_cache_log" facility="local0" severity="notice") :syslogtag, isequal, "pseudolog_squid_cache_log" @syslog:514ログがたまるので、1週間でローテートします。
proxy-ad/squid_log/var/log/squid/*.log { daily rotate 8 compress missingok notifempty postrotate /bin/systemctl restart rsyslog endscript }証明書
このほか、証明書の準備 で作成した、秘密鍵と証明書も同じディレクトリに配置します。
コンテナの作成
まず、IPv6のネットワークをつくります。
サブネットは適宜修正ください。# docker network create --ipv6 --driver=bridge --subnet=fd5a:ceb9:ed8d:a::/64 br_proxy_nw
でネットワークをつくったら、IPv6が有効になっているかを確認します。
# docker network inspect br_proxy_nw | grep IPv6 "EnableIPv6": true,ビルドし、コンテナを起動させます。
# docker-compose build # docker-compose up -d動作確認
テストには上記の構成ファイルの説明で例示した URLフィルタのリスト を利用します。
動作確認用のユーザは前述の ADユーザの準備 で作成した、以下を利用します。
カテゴリ ユーザ名 全許可ユーザ soumu.tarp 一部許可ユーザ jinji.jiro 通常ユーザ josys.saburo 非ドメインユーザ ローカルadministrator
認証ダイアログ表示はキャンセルするアクセス先と想定される動作は以下です。
URL 想定される動作 https://ftp.riken.jp/ 全員アクセスOK https://ugtop.com/ OU=employee所属の
ユーザはアクセスOKhttps://qiita.com/ OU=employee所属で
セキュリティグループがProxyUnlimit/ProxyLimitの
ユーザはアクセスOKhttps://crt.sh/ OU=employee所属で
セキュリティグループがProxyUnlimitの
ユーザはアクセスOKhttps://qiita.com/bashaway 全員アクセスNG また、非ドメインユーザの確認として、CentOSのyumアップデートを実施します。
全許可ユーザ(soumu.taro)
https://ftp.riken.jp/
アクセスOKTCP_TUNNEL/200 8880 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 -https://ugtop.com/
アクセスOKTCP_DENIED/407 4061 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT ugtop.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/200 2499 GET https://ugtop.com/ PROSPER2\\soumu.taro HIER_DIRECT/219.94.129.26 text/html TCP_MISS/304 235 GET https://ugtop.com/index.css PROSPER2\\soumu.taro HIER_DIRECT/219.94.129.26 - TCP_MISS/304 233 GET https://ugtop.com/title2002.gif PROSPER2\\soumu.taro HIER_DIRECT/219.94.129.26 - TCP_DENIED/407 4120 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_DENIED/407 4482 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_MISS/302 556 GET http://www.ugtop.com/favicon.ico PROSPER2\\soumu.taro HIER_DIRECT/219.94.129.26 text/htmlhttps://qiita.com/
アクセスOKTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT qiita.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/200 16714 GET https://qiita.com/ PROSPER2\\soumu.taro HIER_DIRECT/2406:da14:add:900:a151:96dc:63d3:7b6 text/html TCP_DENIED/407 4077 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4439 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT cdn.qiita.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/304 435 GET https://cdn.qiita.com/assets/public/style-62725e4620e989e818f0a740fac95a08.min.css PROSPER2\\soumu.taro HIER_DIRECT/2600:9000:208e:bc00:13:f1f4:ebc0:93a1 - TCP_MISS/304 435 GET https://cdn.qiita.com/assets/public/bundle-64959777c315371f97ccc3068267aeec.min.js PROSPER2\\soumu.taro HIER_DIRECT/2600:9000:208e:bc00:13:f1f4:ebc0:93a1 - TCP_DENIED/407 4077 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4439 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html TCP_MISS/304 453 GET https://cdn.qiita.com/assets/public/hero-background-885fd333ab5d2e15054b2b2b3b970ebc.png PROSPER2\\soumu.taro HIER_DIRECT/2600:9000:208e:bc00:13:f1f4:ebc0:93a1 - NONE/200 0 CONNECT cdn.qiita.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/304 545 GET https://cdn.qiita.com/assets/public/fontawesome-webfont-674f50d287a8c48dc19ba404d20fe713.eot? PROSPER2\\soumu.taro HIER_DIRECT/2600:9000:208e:bc00:13:f1f4:ebc0:93a1 -https://crt.sh/
アクセスOKTCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html NONE/200 0 CONNECT crt.sh:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/200 4530 GET https://crt.sh/ PROSPER2\\soumu.taro HIER_DIRECT/2a0e:ac00:c7:d449::5bc7:d449 text/html TCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html NONE/200 0 CONNECT crt.sh:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/200 4820 GET https://crt.sh/sectigo_s.png PROSPER2\\soumu.taro HIER_DIRECT/2a0e:ac00:c7:d449::5bc7:d449 image/pnghttps://qiita.com/bashaway
アクセスNGTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT qiita.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_DENIED/403 4604 GET https://qiita.com/bashaway PROSPER2\\soumu.taro HIER_NONE/- text/html TCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT qiita.com:443 PROSPER2\\soumu.taro HIER_NONE/- -一部許可ユーザ(jinji.jiro)
https://ftp.riken.jp/
アクセスOKTCP_TUNNEL/200 8880 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 -https://ugtop.com/
アクセスOKTCP_DENIED/407 4061 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT ugtop.com:443 PROSPER2\\jinji.jiro HIER_NONE/- - TCP_MISS/200 2499 GET https://ugtop.com/ PROSPER2\\jinji.jiro HIER_DIRECT/219.94.129.26 text/html TCP_MISS/304 235 GET https://ugtop.com/index.css PROSPER2\\jinji.jiro HIER_DIRECT/219.94.129.26 - TCP_MISS/304 233 GET https://ugtop.com/title2002.gif PROSPER2\\jinji.jiro HIER_DIRECT/219.94.129.26 - TCP_DENIED/407 4120 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_DENIED/407 4482 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_MISS/302 556 GET http://www.ugtop.com/favicon.ico PROSPER2\\jinji.jiro HIER_DIRECT/219.94.129.26 text/htmlhttps://qiita.com/
アクセスOKTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT qiita.com:443 PROSPER2\\jinji.jiro HIER_NONE/- - TCP_MISS/200 16734 GET https://qiita.com/ PROSPER2\\jinji.jiro HIER_DIRECT/2406:da14:add:902:a992:3bc3:1c46:cdfa text/html TCP_DENIED/407 4077 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4439 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT cdn.qiita.com:443 PROSPER2\\jinji.jiro HIER_NONE/- - TCP_MISS/304 435 GET https://cdn.qiita.com/assets/public/style-62725e4620e989e818f0a740fac95a08.min.css PROSPER2\\jinji.jiro HIER_DIRECT/2600:9000:208e:ca00:13:f1f4:ebc0:93a1 - TCP_MISS/304 435 GET https://cdn.qiita.com/assets/public/bundle-64959777c315371f97ccc3068267aeec.min.js PROSPER2\\jinji.jiro HIER_DIRECT/2600:9000:208e:ca00:13:f1f4:ebc0:93a1 - TCP_DENIED/407 4077 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html TCP_MISS/304 453 GET https://cdn.qiita.com/assets/public/hero-background-885fd333ab5d2e15054b2b2b3b970ebc.png PROSPER2\\jinji.jiro HIER_DIRECT/2600:9000:208e:ca00:13:f1f4:ebc0:93a1 - TCP_DENIED/407 4439 CONNECT cdn.qiita.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT cdn.qiita.com:443 PROSPER2\\jinji.jiro HIER_NONE/- - TCP_MISS/304 545 GET https://cdn.qiita.com/assets/public/fontawesome-webfont-674f50d287a8c48dc19ba404d20fe713.eot? PROSPER2\\jinji.jiro HIER_DIRECT/2600:9000:208e:ca00:13:f1f4:ebc0:93a1 -TCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT crt.sh:443 PROSPER2\\jinji.jiro HIER_NONE/- - NONE/403 4622 GET https://crt.sh/ PROSPER2\\jinji.jiro HIER_NONE/- text/html TCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT crt.sh:443 PROSPER2\\jinji.jiro HIER_NONE/- -TCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\jinji.jiro HIER_NONE/- - NONE/403 4633 GET https://qiita.com/bashaway PROSPER2\\jinji.jiro HIER_NONE/- text/html TCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\jinji.jiro HIER_NONE/- -通常ユーザの場合(josys.saburo)
https://ftp.riken.jp/
アクセスOKTCP_TUNNEL/200 8880 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 -https://ugtop.com/
アクセスOKTCP_DENIED/407 4061 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT ugtop.com:443 PROSPER2\\josys.saburo HIER_NONE/- - TCP_MISS/200 2499 GET https://ugtop.com/ PROSPER2\\josys.saburo HIER_DIRECT/219.94.129.26 text/html TCP_MISS/304 235 GET https://ugtop.com/index.css PROSPER2\\josys.saburo HIER_DIRECT/219.94.129.26 - TCP_MISS/304 233 GET https://ugtop.com/title2002.gif PROSPER2\\josys.saburo HIER_DIRECT/219.94.129.26 - TCP_DENIED/407 4120 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_DENIED/407 4482 GET http://www.ugtop.com/favicon.ico - HIER_NONE/- text/html TCP_MISS/302 556 GET http://www.ugtop.com/favicon.ico PROSPER2\\josys.saburo HIER_DIRECT/219.94.129.26 text/htmlhttps://qiita.com/
アクセスNGTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\josys.saburo HIER_NONE/- - NONE/403 4667 GET https://qiita.com/ PROSPER2\\josys.saburo HIER_NONE/- text/html TCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\josys.saburo HIER_NONE/- -https://crt.sh/
アクセスNGTCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT crt.sh:443 PROSPER2\\josys.saburo HIER_NONE/- - NONE/403 4660 GET https://crt.sh/ PROSPER2\\josys.saburo HIER_NONE/- text/html TCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT crt.sh:443 PROSPER2\\josys.saburo HIER_NONE/- -https://qiita.com/bashaway
アクセスNGTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\josys.saburo HIER_NONE/- - NONE/403 4669 GET https://qiita.com/bashaway PROSPER2\\josys.saburo HIER_NONE/- text/html TCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT qiita.com:443 PROSPER2\\josys.saburo HIER_NONE/- -非ドメインユーザで認証キャンセル
ローカルユーザでログインすると、ダイアログが表示されるので、「キャンセル」で閉じる
https://ftp.riken.jp/
アクセスOKTCP_TUNNEL/200 8880 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 -https://ugtop.com/
アクセスNGTCP_DENIED/407 4061 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4750 CONNECT ugtop.com:443 PROSPER2\\administrator HIER_NONE/- text/htmlhttps://qiita.com/
アクセスNGTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4754 CONNECT qiita.com:443 PROSPER2\\administrator HIER_NONE/- text/htmlhttps://crt.sh/
アクセスNGTCP_DENIED/407 4049 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/407 4740 CONNECT crt.sh:443 PROSPER2\\administrator HIER_NONE/- text/htmlhttps://qiita.com/bashaway
アクセスNGTCP_DENIED/407 4061 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT qiita.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4750 CONNECT qiita.com:443 PROSPER2\\administrator HIER_NONE/- text/htmlこの時の接続エラーはsquidのエラーページではなく、ブラウザのエラーページとなります。
システムユーザ(yumコマンドによるリポジトリへのアクセス)
以下のようにproxy設定を追記する。
/etc/yum.conf--------8<----(snip)----8<-------- proxy=http://proxy-ad.prosper2.net:8081/ --------8<----(snip)----8<--------あとは、
yum update
を走らせる。TCP_MISS/200 995 GET http://mirrorlist.centos.org/? - HIER_DIRECT/2604:1580:fe02:2::10 text/plain TCP_MISS/200 1025 GET http://mirrorlist.centos.org/? - HIER_DIRECT/2604:1580:fe02:2::10 text/plain TCP_MISS/200 1049 GET http://mirrorlist.centos.org/? - HIER_DIRECT/2604:1580:fe02:2::10 text/plain TCP_MISS/200 4110 GET http://ftp.jaist.ac.jp/pub/Linux/CentOS/7.7.1908/os/x86_64/repodata/repomd.xml - HIER_DIRECT/2001:df0:2ed:feed::feed application/xml TCP_MISS/200 5854 GET http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/7/x86_64/repodata/repomd.xml - HIER_DIRECT/2001:df0:2ed:feed::feed application/xml TCP_MISS/200 3367 GET http://ftp.jaist.ac.jp/pub/Linux/CentOS/7.7.1908/extras/x86_64/repodata/repomd.xml - HIER_DIRECT/2001:df0:2ed:feed::feed application/xml TCP_MISS/200 3334 GET http://yum.mariadb.org/10.4/centos7-amd64/repodata/repomd.xml - HIER_DIRECT/142.4.217.28 application/xml TCP_MISS/200 3381 GET http://ftp.jaist.ac.jp/pub/Linux/CentOS/7.7.1908/updates/x86_64/repodata/repomd.xml - HIER_DIRECT/2001:df0:2ed:feed::feed application/xml TCP_MISS/200 1039445 GET http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/7/x86_64/repodata/66b3561eb58c5f02cd36cf21cb7a1a0a3f564932bfa268c1113e4f7741f93672-updateinfo.xml.bz2 - HIER_DIRECT/2001:df0:2ed:feed::feed application/x-bzip2 TCP_MISS/200 7053786 GET http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/7/x86_64/repodata/b4f2590ec8c2474cba36dd314b195fd8df46b7e51fc49eafabdf23b6c0219a23-primary.sqlite.bz2 - HIER_DIRECT/2001:df0:2ed:feed::feed application/x-bzip2 TCP_TUNNEL/200 11011 CONNECT mirrors.fedoraproject.org:443 - HIER_DIRECT/2604:1580:fe00:0:dead:beef:cafe:fed1 -squidログの中身
whitelistの場合
インターセプトせず、トンネルしていることがわかる。TCP_TUNNEL/200 8880 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 - TCP_TUNNEL/200 3729 CONNECT ftp.riken.jp:443 - HIER_DIRECT/134.160.38.1 -ユーザを認識したうえでアクセス可となる場合
コード 407 で認証要求が発せられ、ACLチェック後にAllowされる。TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html NONE/200 0 CONNECT ugtop.com:443 PROSPER2\\soumu.taro HIER_NONE/- - TCP_MISS/200 2499 GET https://ugtop.com/ PROSPER2\\soumu.taro HIER_DIRECT/219.94.129.26 text/htmlユーザを認識したうえでアクセス不可となる場合
コード 407 で認証要求が発せられ、ACLチェック後にDenyされる。TCP_DENIED/407 4411 CONNECT crt.sh:443 - HIER_NONE/- text/html TCP_DENIED/200 0 CONNECT crt.sh:443 PROSPER2\\jinji.jiro HIER_NONE/- - NONE/403 4622 GET https://crt.sh/ PROSPER2\\jinji.jiro HIER_NONE/- text/html認証要求にこたえられない場合
コード 407 で認証要求が発せられ、応じられないので、クライアントとしてエラーになる。(ブラウザのエラー画面)TCP_DENIED/407 4061 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4423 CONNECT ugtop.com:443 - HIER_NONE/- text/html TCP_DENIED/407 4750 CONNECT ugtop.com:443 PROSPER2\\administrator HIER_NONE/- text/html中身の解説
Dockerfile
Dockerfileの順番で解説していきます。
イメージCentOS8を利用してます。
NTLM認証によるAD連携をSSOで行うため、sambaとwinbindを入れています。
最後にSSLインターセプトのための証明書を保管するディレクトリを作成しています。DockerfileFROM centos:centos8 RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ; \ dnf -y update ; dnf -y install epel-release rsyslog logrotate cronie ; \ rm -f /etc/logrotate.d/syslog ; \ dnf -y install squid samba samba-winbind openldap-clients authselect samba-winbind-clients ; \ mkdir /etc/squid/certs ;\ systemctl enable squidなお、手動で実施すると、以下のような出力になります。
(最初はディレクトリが無かったのでエラーになっています)# /usr/lib64/squid/security_file_certgen -c -s /var/local/squid/ssl_db -M 4MB Initialization SSL db... /usr/lib64/squid/security_file_certgen: Cannot create /var/local/squid/ssl_db # mkdir /var/local/squid # chown squid.squid /var/local/squid # /usr/lib64/squid/security_file_certgen -c -s /var/local/squid/ssl_db -M 4MB Initialization SSL db... Doneここは必要なファイルをローカルからコンテナへコピーしているだけです。
ファイルは空でもよいですが、ファイル自体が存在していないとエラーになります。DockerfileCOPY squid.conf /etc/squid COPY icacert.pem /etc/squid/certs COPY icaprivkey.pem /etc/squid/certs COPY squid_log /etc/logrotate.d COPY blacklist /etc/squid COPY whitelist /etc/squid COPY permlist /etc/squid COPY intralist /etc/squid COPY rsyslog.conf /etc COPY smb.conf /etc/samba COPY docker-entrypoint.sh /usr/local/bin/squidでSSLインターセプトするため、一時的にsquid自身がアクセス先のサーバ証明書を作成します。
そのサーバ証明書を入れておくディレクトリの作成と、ディレクトリの初期化を行います。
squidがアクセスする必要があるので、オーナーを変更します。DockerfileRUN mkdir /var/local/squid ;\ /usr/lib64/squid/security_file_certgen -c -s /var/local/squid/ssl_db -M 4MB ;\ chown -R squid.squid /var/local/squid ;\初回起動時の処理を行うためのヘルパースクリプトをコンテナ内にコピーしています。
Dockerfileln -s usr/local/bin/docker-entrypoint.sh / ENTRYPOINT ["docker-entrypoint.sh"] CMD [ "/usr/sbin/init" ]docker-entrypoint.sh
初回起動時のみ処理させたいものをここにまとめています。
ヘルパースクリプトの動作は dockerで初回起動時のみ特定の処理を行うヘルパースクリプト に書きました。smbとwinbindはインストールしただけでは、enableになっていないので、それを初回起動の判断条件としています。
認証にwinbindを利用するコマンドを実施後、net ads join -U
で自身のコンピュータをADに登録します。
登録時はドメインユーザであればOKですので、検索用に作成したユーザを指定しています。
その後、sambaとwinbindを有効化しています。docker-entrypoint.sh#!/bin/sh if [ ! -e /etc/systemd/system/multi-user.target.wants/smb.service ] ; then authselect select winbind --force net ads join -U searchuser%s3arch#PWD systemctl enable smb systemctl enable winbind systemctl start smb systemctl start winbind fi exec "$@"なお、手動で実施すると、以下のような出力になります。
# net ads join -U searchuser%s3arch#PWD Using short domain name -- PROSPER2 Joined 'PROXY-AD' to dns domain 'prosper2.net' No DNS domain configured for proxy-ad. Unable to perform DNS Update. DNS update failed: NT_STATUS_INVALID_PARAMETERエラーっぽい出力になっていますが、以下のようにコンピュータが登録されます。
squid.conf
認証がらみが多く出てきます。
各セクションごとに説明しますが、コメントは外しています。NTLM認証のヘルパーを使います。
以下設定では子プロセスを5としているので、大量のユーザで利用する場合は、チューニングが必要です。squid.confauth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp auth_param ntlm children 5ここは、SSOのユーザがどのセキュリティグループに所属しているのかを
ext_ldap_group_acl
でチェックします。
セキュリティグループがProxyUnlimitなら、squid内でgr_unlimitというaclを定義しています。
セキュリティグループがProxyLimitなら、squid内でgr_limitというaclを定義しています。
このままだと、どちらのセキュリティグループにも所属していないと、後にでてくる http_access で不具合がでます。
なので、ext_ldap_group_acl
を再度処理して、SSOユーザがOU=employeeに所属していれば、gr_employee
をいうaclを定義しています。
ベースDNをそのままにして、検索フィルタでOUを抜き出したいのですが、OU=employee配下のユーザでOU=employee配下のセキュリティグループに所属していないと、memberOf属性で検索ができない。加えて、DN属性にはワイルドカードが利用できないので、CN=*,OU=employee,DC=prosper2,DC=net
という検索ができない。そのため、このような回避策をしています。squid.confexternal_acl_type security_group %LOGIN /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "ou=employee,dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 -f '(&(objectclass=person)(sAMAccountName=%u)(memberOf=CN=%g,ou=employee,dc=prosper2,dc=net))' external_acl_type ou_check %LOGIN /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "ou=employee,dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 -f '(&(objectclass=person)(sAMAccountName=%u))' acl gr_unlimit external security_group ProxyUnlimit acl gr_limit external security_group ProxyLimit acl gr_employee external ou_check employee
ext_ldap_group_acl
のオプションなどは、以下のとおりです。# LDAP search helper : check ActiveDirectory Security Group # -v 3 : use LDAP version 3 # -P : persistent LDAP connection # -R : do not follow referrals # -S : Strip Domain name # -b : Base DN (search group) # -D -w : bind DN (search user) and password # -h : LDAP server (AD DS) # -f : filter %u:User %g:Gourp # %LOGIN : SSO login userこのあたりは、デフォルトの動作とほぼ同じです。
ただし、proxyで許可するポートを http/https/ftp に限定しています。squid.confacl manager proto cache_object acl localhost src localhost acl localhost src 127.0.0.1/32 acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https #acl Safe_ports port 70 # gopher #acl Safe_ports port 210 # wais #acl Safe_ports port 1025-65535 # unregistered ports #acl Safe_ports port 280 # http-mgmt #acl Safe_ports port 488 # gss-http #acl Safe_ports port 591 # filemaker #acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT # Allow cache http_access allow localhost manager http_access deny manager # Deny not Safe_ports http_access deny !Safe_ports # Deny CONNECT request on not SSL_ports http_access deny CONNECT !SSL_portssquidの条件判定はFWなんかと同じで、上からチェックしてマッチしたらそこで終了です。
前述したext_ldap_group_acl
は http_access句でチェックされようとするタイミングで発動するため、blacklistとwhitelistはldap処理の前にもってきています。squid.conf# Deny Blacklist sites acl blacklist url_regex -i "/etc/squid/blacklist" http_access deny blacklist # Allow Whitelist sites acl whitelist url_regex -i "/etc/squid/whitelist" http_access allow whitelistドメインユーザでなければ拒否します。(ホワイトリストは前述でallowのため、影響ありません。)
squid.conf# Deny not Domain User http_access deny !gr_unlimit !gr_limit !gr_employeeセキュリティグループ:ProxyUnlimit は、接続先によらず許可です。
squid.conf# permit : ProxyUnlimit http_access allow gr_unlimitセキュリティグループ:ProxyLimit は、permlistにあるサイトは許可です。
squid.conf# permit : ProxyLimit and permlist acl permlist url_regex -i "/etc/squid/permlist" http_access allow gr_limit permlistOU:employeeのユーザはintralistにあるサイトは許可です。
squid.conf# permit : No security gourp and intralist acl intralist url_regex -i "/etc/squid/intralist" http_access allow gr_employee intralistこれまでに許可されなかったクライアントは拒否です。
squid.conf# deny : default http_access deny all待ち受けを8081/tcpとして、SSL_BUMPしています。
SSL_BUMPは子プロセスを5としているので、大量のユーザで利用する場合は、チューニングが必要です。
whitelistはSSL_BUMPせず、そのまま転送します。(これしないと yum でエラー出る)squid.confhttp_port 8081 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/certs/icacert.pem key=/etc/squid/certs/icaprivkey.pem sslcrtd_program /usr/lib64/squid/security_file_certgen -s /var/local/squid/ssl_db -M 4MB sslcrtd_children 5 ssl_bump bump !whitelist sslproxy_cert_error allow intralist sslproxy_cert_error deny allあとはデフォルトのまま。
squid.confvisible_hostname proxy-ad coredump_dir /var/spool/squid refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320トラブルシューティング
winbindがうまく動作しない場合、ldapフィルタが思うように動作しない場合など、以下の通りチェックしてみます。
winbindの動作
正常に接続できるかの確認
# wbinfo -t checking the trust secret for domain PROSPER2 via RPC calls succeededユーザリストが取得できるか
# wbinfo -u PROSPER2\administrator PROSPER2\guest PROSPER2\krbtgt PROSPER2\aad_7dfc1e6f942a PROSPER2\msol_7dfc1e6f942a PROSPER2\soumu.taro PROSPER2\jinji.jiro PROSPER2\josys.saburo PROSPER2\searchuser指定ユーザで認証できるか
# wbinfo -a PROSPER2.NET\\searchuser%s3arch#PWD plaintext password authentication succeeded challenge/response password authentication succeeded
ldapsearch
windowsのログインユーザを指定して、対象ユーザの情報を表示
# ldapsearch -b "dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 "sAMAccountName=soumu.taro"フィルタを組み合わせて、対象ユーザの情報を表示
# ldapsearch -b "dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 \ '(&(objectclass=person)(sAMAccountName=soumu.taro)(memberOf=CN=ProxyUnlimit,OU=employee,DC=prosper2,DC=net))'フィルタを組み合わせて、対象ユーザの情報を表示
(この場合、jinji.jiroはProxyUnlimitのmemberOfではないため、表示されない)# ldapsearch -b "dc=prosper2,dc=net" -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 \ '(&(objectclass=person)(sAMAccountName=jinji.jiro)(memberOf=CN=ProxyUnlimit,OU=employee,DC=prosper2,DC=net))'ext_ldap_group_acl
squid.conf で記載しているコマンドは、そのままコマンドラインで確認できる。
ログイン名とセキュリティグループの組み合わせが正しいかをチェック# /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "dc=prosper2,dc=net" \ -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 \ -f '(&(objectclass=person)(sAMAccountName=%u)(memberOf=CN=%g,ou=employee,dc=prosper2,dc=net))' soumu.taro ProxyUnlimit OK jinji.jiro ProxyUnlimit ERR josys.saburo ProxyUnlimit ERR soumu.taro ProxyLimit ERR jinji.jiro ProxyLimit OK josys.saburo ProxyLimit ERRログイン名とがOU:employeeに存在するかをチェック
(引数を1つしか指定していないため、第2引数はなんの文字列でもかまわない)# /usr/lib64/squid/ext_ldap_group_acl -v 3 -P -R -S -b "ou=employee,dc=prosper2,dc=net" \ -D searchuser@prosper2.net -w s3arch#PWD -h 10.254.10.241 \ -f '(&(objectclass=person)(sAMAccountName=%u))' soumu.taro ABCDEFG OK jinji.jiro ABCDEFG OK josys.saburo ABCDEFG OK searchuser ABCDEFG ERRさいごに
前回チャレンジしたのが2014年の squidとActiveDirectoryの連携 でした。
今回はSSLインターセプトを追加してDockerコンテナで作成しましたが、squid4.4になっても大きく変わっていなかったので、比較的すんなり検証できました。次はKerberos認証にチャレンジ予定です。
出典
http://www.prosper2.org/devwiki/index.php?squid%E3%81%A8ActiveDirectory%E3%81%AE%E9%80%A3%E6%90%BA
https://www7390uo.sakura.ne.jp/wordpress/archives/777
https://smoothnet.org/squid-v3-5-proxy-with-ssl-bump/
https://social.technet.microsoft.com/Forums/lync/en-US/24e0eec0-7984-4bc3-b2e8-319be2d57112/ldap-filter-limiting-to-specific-ou
https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx
- 投稿日:2020-02-25T03:20:07+09:00
dockerでsinatraサーバーを起動しよう。
この記事で得られるもの(目的)
- Virtual MachineとDockerの起動方式
- Dockerfileの書き方
- DockerでImageを作る方法
- DockerでContainerを起動する方法
この記事で扱わないこと
- Dockerのインストール
Agenda
- Dockerとは
- Virtual MachineとDockerの起動方式
- SintraサーバーのDocker Imageを作る
- Imageに基づいたContainerを起動させる
Dockerとは
DockerはImageに基づいてContainerを起動したりするプログラムです。
Containerは隔離された空間でProcessを動く技術です。
ImageはどういうContainerを作るかについて記録されている設計図みたいなことです。Virtual MachineとDockerの起動方式
Virtual Machineの起動方式
(出処)Dockerホームページ
例えば、WindowsでLinuxを実行したいとなった場合、
Virtual Machine(Virtual Boxなど)ではHost OS(Windows)の上にGuest OS(Linux)をインストールしてApp Serverを立ち上げることになります。
つまりHost OSとは別のResourceを全部作り直します。Dockerの起動方式
(出処)Dockerホームページ
DockerはHost OSのResourceを共有してもらってContainerを起動させる。
だから、VMの方式よりOverheadがかなり少なくなるし、実際使って見ても結構早いですね。SintraサーバーのDocker Imageを作る
まず、DockerがContainerを実行するまでの簡略な順を見ましょう。
DockerはDockerfileに基づいてDocker Imageを作ります。
その後、Docker Imageに基づいてDocker Containerを起動させます。じゃー、SinatraのAppのための環境を作るための書いて見ましょう。
ファイルの位置: /Dockerfile
1 # baseになるimage 2 FROM ruby:2.6.5 3 # このDockerfileを作った人 4 MAINTAINER jinument@gmail.com 5 6 # Docker Containerの環境変数を設定 7 # ENV 環境変数名 環境変数値 8 ENV WORKSPACE /app 9 10 # HostのファイルをContainer内に追加 11 # ADD Hostのファイル経路 Container内の経路 12 # Hostの現在DirectoryにあるGemfileと始まるファイルを 13 # Container内のWorkspace(ここでは/app)に追加 14 ADD ./Gemfile* $WORKSPACE/ 15 # Container内の作業Directoryを変更する 16 # Container内でcd(change directory)コマンドをうつのと同じ 17 WORKDIR $WORKSPACE 18 # Container内で実行するコマンドを定義 19 # このコマンドの意味は 20 # Container内の/app/でbundle installを実行してという意味 21 RUN bundle install 22 23 ADD . $WORKSPACE 24 25 # ContainerのPortを開放する 26 # このコマンドでHostから4567ポートで 27 # Container内の4567にアクセスできるようになる 28 # (参考)Sinatraのサーバーポートが4567だからここで4567を開放する 29 EXPOSE 4567 30 31 # Containerのbuildが出来上がって 32 # Containerが実行するタイミングでこのコマンドが実行される 33 CMD ['ruby', 'app.rb']ファイルの位置: /app.rb
1 require 'sinatra' 2 3 set :bind, '0.0.0.0' 4 5 get '/health_check' do 6 'health check' 7 endファイルの位置: /Gemfile
1 source 'https://rubygems.org' 2 3 gem 'sinatra', '2.0.8'以下のファイルを同じDirectoryに置いておいて以下のコマンドを実行することで、Docker Imageを作る。
docker build -t sinatra_image .
-t sinatra_image
は作るimageの名前を指定すること。
.
は現在DirectoryにあるDockerfileを利用してDocker Imageを作るという意味。
docker build -t sinatra_image .
このコマンドを打ったら、Dockerは以下のログを吐き出します。
ログを見ると内がDockerfileに書いた部分が一個づつ実行されることが確認できる。
(Layerという概念もあるが、この記事では扱いません。)lee@leeui-MacBookAir ~/workspace/qiita docker build -t make_image . Sending build context to Docker daemon 6.144kB Step 1/9 : FROM ruby:2.6.5 ---> a161c3e3dda8 Step 2/9 : MAINTAINER jinument@gmail.com ---> Running in ce277718c930 Removing intermediate container ce277718c930 ---> b56f7155a807 Step 3/9 : ENV WORKSPACE /app ---> Running in 3869474ae7c2 Removing intermediate container 3869474ae7c2 ---> d17245751687 Step 4/9 : ADD ./Gemfile* $WORKSPACE/ ---> 616bacbaa111 Step 5/9 : WORKDIR $WORKSPACE ---> Running in 0a6fd625644c Removing intermediate container 0a6fd625644c buffers ---> 2ef75a288ed5 Step 6/9 : RUN bundle install ---> Running in df916cdef1f6 Fetching gem metadata from https://rubygems.org/.......... Using bundler 1.17.2 Fetching ruby2_keywords 0.0.2 Installing ruby2_keywords 0.0.2 Fetching mustermann 1.1.1 Installing mustermann 1.1.1 Fetching rack 2.2.2 Installing rack 2.2.2 Fetching rack-protection 2.0.8 Installing rack-protection 2.0.8 Fetching tilt 2.0.10 Installing tilt 2.0.10 Fetching sinatra 2.0.8 Installing sinatra 2.0.8 Bundle complete! 1 Gemfile dependency, 7 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. Removing intermediate container df916cdef1f6 ---> 2ce2af9012c7 Step 7/9 : ADD . $WORKSPACE ---> eec1a89dd292 Step 8/9 : EXPOSE 4567 ---> Running in 4b7d253f9875 Removing intermediate container 4b7d253f9875 ---> fca62715a481 Step 9/9 : CMD ['ruby', 'app.rb'] ---> Running in dd5069206a4a Removing intermediate container dd5069206a4a ---> 41e7c0189e0c Successfully built 41e7c0189e0c Successfully tagged sinatra_image:latestじゃー、Imageがちゃんと作られたか以下のコマンドで確認して見ましょう。
⚙ lee@leeui-MacBookAir ~/workspace/qiita docker images REPOSITORY TAG IMAGE ID CREATED SIZE sinatra_image latest 41e7c0189e0c 32 minutes ago 872MBImageに基づいたContainerを起動させる
⚙ lee@leeui-MacBookAir ~/workspace/qiita docker run -d -p 4567:4567 sinatra_image 023f6c6e7d27a7368a3440163c7faeda406c3e8cc36ee7d254e50c56551200af現状Container化されているものの状況を確認するコマンドは以下になります。
docker ps -a⚙ lee@leeui-MacBookAir ~/workspace/qiita docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 023f6c6e7d27 sinatra_image "/bin/sh -c '['ruby'…" 3 minutes ago Exited (127) 3 minutes ago boring_northcuttlocalhost:4567/health_checkにアクセスして意図通り動いているか確認します。
- 投稿日:2020-02-25T00:39:13+09:00
Dockerでよく使うコマンド
Dockerでよく使うコマンドについて記載
#dockerのバージョン確認 $docker version #dockerの実行環境確認 $docker info #イメージをダウンロード $docker pull [OPTIONS] NAME[:TAG|@DIGEST] #例 $docker pull centos:7.1.1503 #イメージの一覧を表示 $docker images [OPTIONS] [REPOSITORY[:TAG]] #イメージの詳細を表示 $docker inspect [OPTIONS] NAME|ID [NAME|ID...] #イメージへタグを設定 $docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] #Dokcer Hubに公開されているイメージの検索 $docker search [OPTIONS] TERM #イメージの更新内容を確認 $docker history [OPTIONS] IMAGE #イメージの削除 $docker rmi [OPTIONS] IMAGE [IMAGE...] #Dokcer Hubにログイン $docker login [OPTIONS] [SERVER] #Docker Hubにイメージをアップロード $docker push [OPTIONS] NAME[:TAG] #コンテナの起動 $docker run [OPTIONS] IMAGE [COMMAND] [ARG...] #例 $docker run centos:7.1.1503 #デタッチド・モードでの実行 例 docker run --name centos01 -d -p 8080:8080 -m=200m --memory-swap=1G --cpu-shares=1024 centos:7.1.1503 #コンテナをターミナルで実行する 例 $docker run -i -t centos:7.1.1503 /bin/bash #バックグラウンドで実行しているコンテナをフォアグラウンドにする $docker attach [OPTION] CONTAINER [CONTAINER...] #コンテナの一覧を表示 $docker ps [OPTIONS] #コンテナの一覧を表示(停止したものも表示) $docker ps -a #コンテナの稼働確認 $docker stats [OPTIONS] [CONTAINER...] #コンテナのログを表示 $docker logs [OPTION] CONTAINER [CONTAINER...] #コンテナのの停止(一定期間が経過したらSIGKILLを送信) $docker stop [OPTION] CONTAINER [CONTAINER...] #コンテナのの停止(すぐ停止) $docker stop [OPTION] CONTAINER [CONTAINER...] #コンテナの再起動 $docker restart [OPTIONS] CONTAINER [CONTAINER...] #コンテナの中断 $docker pause CONTAINER [CONTAINER...] #コンテナの再開 $docker unpause CONTAINER [CONTAINER...] #起動中のコンテナに入ってプロセスを実行 $docker exec [OPTIONS] CONTAINER COMMAND [ARG...] #起動中のコンテナに入ってプロセスを実行 例 $docker exec -i -t xxxxxx /bin/bash #コンテナのプロセス確認 $docker top CONTAINER [ps OPTIONS] #コンテナのポート確認 $docker port CONTAINER [PRIVATE_PORT[/PROTO]] #コンテナの名前変更 $docker rename CONTAINER NEW_NAME #コンテナ内からファイルをコピー $docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- #コンテナ内からファイルをコピー 例 $docker cp nginx01:/etc/test.ttx /tmp/test.txt #コンテナ内へファイルをコピー $docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH #コンテナ内へファイルをコピー $docker cp /tmp/test.txt nginx01:/etc/test.txt #コンテナの削除 $docker rm [OPTIONS] CONTAINER [CONTAINER...] #コンテナの強制削除 $docker rm -f [OPTIONS] CONTAINER [CONTAINER...] #止まっているコンテナを全て削除 例 $docker rm $(docker ps -aq --filter='status=exited') #コンテナへの変更内容を確認するためのコマンド。 $docker diff [OPTIONS] CONTAINER #例 $docker diff $(docker ps -lq) #コンテナからイメージを作成 $docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] #コンテナからイメージを出力 $docker container export [OPTIONS] CONTAINER #コンテナからイメージを出力 例 $docker container export nginx01 > nginx01.tar #イメージをインポート $docker image import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] #イメージを保存 $docker save [OPTIONS] IMAGE [IMAGE...] #イメージの読み込み $docker load [OPTIONS] #Dockerfileからイメージの作成 $docker build [OPTIONS] PATH | URL | - #Dockerfileからイメージの作成 例 $docker build https://github.com/docker/rootfs.git#container:docker以上
参考
http://docs.docker.jp/engine/reference/commandline/index.html