2023年2月27日月曜日

Flask-Pydantic を使ってみた

Flask-Pydantic を使ってみた

概要

flask はリクエストの情報は request.json などで受け取り必要に応じて自分で Python のモデルクラスに変換します

pydantic を使えば自動でモデルに変換してくれたりバリデーションを簡単に実装できる仕組みを提供してくれます

今回は flask の拡張である Flask-Pydantic を使って flask 上で pydantic を使う方法を紹介します

環境

  • macOS 11.7.3
  • Python 3.10.2
  • flask 2.2.3
  • Flask-pydantic 0.11.0
  • pydantic 1.10.5

インストール

  • pipenv install Flask-Pydantic

サンプルコード: POST時のリクエストボディを自動でモデルに変換する

from typing import Optional
from flask import Flask
from pydantic import (BaseModel,
                      validator)
from flask_pydantic import validate

app = Flask(__name__)


class ResponseModel(BaseModel):
  id: int
  age: int
  name: str
  nickname: Optional[str]


class RequestBodyModel(BaseModel):
  name: str
  nickname: Optional[str]

  @validator("name")
  def check_name(cls, v, values, **kwargs):
      if v != "hawksnowlog":
          raise ValueError()
      return v
      

@app.route("/", methods=["POST"])
@validate()
def post(body: RequestBodyModel):
  name = body.name
  nickname = body.nickname
  return ResponseModel(name=name,
                       nickname=nickname,
                       id=0,
                       age=1000)

ちょっと解説

pydantic.BaseModel を継承してリクエストとレスポンスモデルは定義します

フィールドの型チェックは自動で行ってくれますが特定の条件でバリデーションしたい場合は pydantic.validator を使ってバリデーションします (この辺りは普通の pydantic の使い方として使えます)

今回はボディを変換してほしいので flask のルーティングの引数に body を指定しています
パスパラメータやクエリストリングも対象にすることができます

動作確認

  • pipenv run flask run

で起動したら curl でリクエストします

  • curl localhost:5000 -XPOST -d '{"name":"hawksnowlog","nickname":"hawk"}' -H 'content-type: application/json'

=> {"id": 0, "age": 1000, "name": "hawksnowlog", "nickname": "hawk"}

最後に

fastapi のように flask でも pydantic を扱うことができました
flask ですでにプロジェクトが動いている場合などには使えるかなと思います

参考サイト

2023年2月24日金曜日

gcloud scp コマンドで実際に実行している素の scp コマンドを表示する方法

gcloud scp コマンドで実際に実行している素の scp コマンドを表示する方法

概要

--dry-run オプションを使用します

環境

  • macOS 11.7.3
  • gcloud 371.0.0

サンプルコマンド

gcloud scp

gcloud compute scp --ssh-key-file="~/.ssh/id_rsa" --dry-run test.text user1@web:~/test.txt

実際に実行される scp コマンド

/usr/bin/scp -i /Users/user1/.ssh/id_rsa -o CheckHostIP=no -o HashKnownHosts=no -o HostKeyAlias=compute.1234567890 -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/Users/user1/.ssh/google_compute_known_hosts test.text user1@xxx.xxx.xxx.xxx:~/test.txt

ちなみに --ssh-key-file のデフォルトパスは ~/.ssh/google_compute_engine なのですでにその名前で鍵がある場合は指定不要です

2023年2月21日火曜日

flask-migrate で sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)")

flask-migrate で sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)")

概要

flask-migrate をアップグレードした際に発生しました
対処方法を紹介します

主に flask db migrate や flask db upgrade コマンド実行時にタイトルのエラーが発生します

環境

  • flask-migrate 2.5.3 -> 4.0.4

対応方法

  • flask-migrate 4.0.4 をインストール
  • プロジェクトを作成
  • 作成したプロジェクトで flask db init
  • マイグレーション用のファイルを適当に作成する
  • 続けて flask db migrate -m “init”
  • ここで作成された「README」「alembic.ini」「env.py」既存のプロジェクトにコピーする
  • 既存のプロジェクトの flask-migrate を 4.0.4 にアップグレードする

2023年2月20日月曜日

RuntimeError: A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead.

RuntimeError: A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead.

概要

flask をアップデートした際に発生しました

環境

  • flask 2.1.1 -> 2.2.3
  • flask-sqlalchemy 2.5.1 -> 3.0.3
    • sqlalchemy 1.4.46 -> 2.0.3

対応方法

自分の環境の対応方法を紹介します

db.init_app(app)

を実行している箇所を削除し

db = SQLAlchemy(app)

で初期化するようにしたら解消しました

Tips

  • db = SQLAlchemy(app) は必ず一箇所で行うこと他で db を使いたい場合は import する
  • db.init_app(app) は普通にコーディングしていたら使わないはず、どうしてもアプリケーションコンテキストを push するようなケースでは意図的に呼び出す感じ

2023年2月17日金曜日

シェルスクリプトでループ時の変数に要素を分割して受け取る方法

シェルスクリプトでループ時の変数に要素を分割して受け取る方法

概要

例えば awk で複数の結果を受け取ってそれをループして各要素を変数に格納する場合などに使えます

環境

  • Ubuntu 18.04
  • bash

サンプルコード

docker service ls | awk 'OFS="," {print $2,$4}' | while IFS=, read -r srv count
do
  echo ${srv}
  echo ${count}
done

解説

docker service ls の結果からサービス名とサービスの稼働数を取得してそれをループでそれぞれ表示しています

awk の結果は OFS="," で csv 形式にします
こうすることで while read 時に IFS=, を設定し awk の csv 結果を分割してすることができます
分割した結果は srv, count という変数にそれぞれ格納されます

for ループでも同じようなことができますがシェルスクリプトで結果をループしたい場合は while read を使う方法をおすすめします

2023年2月16日木曜日

Ubuntu20.04 に certbot をインストール

Ubuntu20.04 に certbot をインストール

概要

過去の手順が少し古くなったのでそれのブラッシュアップ版になります

certbot + nginx の公式手順になります

環境

  • Ubuntu 20.04
  • certbot 1.32.2

certbot のインストール

  • sudo snap install core; sudo snap refresh core
  • sudo apt-get remove certbot
  • sudo snap install --classic certbot
  • sudo ln -s /snap/bin/certbot /usr/bin/certbot

nginx のインストール

  • sudo apt -y update
  • sudo apt -y install nginx-core

IP を A レコードに登録

たぶん必要

80ポートを Let’sEncrypt からアクセスできるようにする

これはいらない?

証明書取得

  • sudo certbot certonly --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): your.mail@address.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): your.domain.com
Requesting a certificate for your.domain.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your.domain.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/your.domain.com/privkey.pem
This certificate expires on 2023-05-15.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

動作確認

  • sudo certbot certificates

削除

  • sudo certbot delete

2023年2月15日水曜日

Gitlab に複数の SAML プロバイダを設定する際の注意事項

Gitlab に複数の SAML プロバイダを設定する際の注意事項

概要

ハマりポイントをメモしておきます

環境

  • Gitlab-ee 15.5.9

ハマリポイント

  • omniauth_auto_sign_in_with_provider に saml, saml_2 という感じで別の識別文字名を設定する
  • omniauth_providers_saml_name に saml, saml_2 といった感じで omniauth_auto_sign_in_with_provider に設定した識別文字列を設定する
  • args.name に omniauth_providers_saml_name と同じ値を設定する
  • args.strategy_class に OmniAuth::Strategies::SAML を設定する
  • assertion_consumer_service_url に omniauth_providers_saml_name が含まれるように設定する (/users/auth/saml_2/callback)
    • IdP 側のコールバックURLも変更するように

2023年2月14日火曜日

UbuntuにActiveDirectoryをdockerで構築する方法

UbuntuにActiveDirectoryをdockerで構築する方法

概要

Samba をベースに bind や ldap と組み合わせると ActiveDirectory DC (Domain Controller) を構築できるようなのでやってみました

環境

  • Ubuntu 18.04
  • Samba 4

使用するイメージ

今回はこちらを使用します

公式などではないので注意が必要です
ActiveDirectory Domain Controller (以下、ADDC) に必要なコンポーネントが一式詰まっているイメージになります

事前準備

いくつか事前準備が必要なのでやっていきます

仮想ネットワークの作成

検証用なので作成します
本来は ADDC を配置したいネットワーク上に配置すれば OK です
またコンポーネントとして DNS (bind) があるので DNS がすでにネットワーク上に存在する場合は一旦停止するか存在しないネットワーク上にデプロイしましょう

  • sudo ifconfig ens192:1 192.168.3.222 netmask 255.255.255.0 up
  • sudo systemctl stop bind9

ADDC用のデータディレクトリ作成

永続化用に作成します

  • mkdir data
  • mkdir config
  • chmod -R 777 data
  • chmod -R 777 cofig

ADDCコンテナの作成

ではコンテナを起動していきます
まずは完成形は以下の通りとなります

docker run -t -i \
  -e "DOMAIN=CORP.EXAMPLE.COM" \
  -e "DOMAINPASS=yourAdminPassword" \
  -e "HOSTIP=192.168.3.222" \
  -e "INSECURELDAP=true" \
  -p 192.168.3.222:53:53 \
  -p 192.168.3.222:53:53/udp \
  -p 192.168.3.222:88:88 \
  -p 192.168.3.222:88:88/udp \
  -p 192.168.3.222:135:135 \
  -p 192.168.3.222:137-138:137-138/udp \
  -p 192.168.3.222:139:139 \
  -p 192.168.3.222:389:389 \
  -p 192.168.3.222:389:389/udp \
  -p 192.168.3.222:445:445 \
  -p 192.168.3.222:464:464 \
  -p 192.168.3.222:464:464/udp \
  -p 192.168.3.222:636:636 \
  -p 192.168.3.222:1024-1044:1024-1044 \
  -p 192.168.3.222:3268-3269:3268-3269 \
  -v /etc/localtime:/etc/localtime:ro \
  -v $(pwd)/data/:/var/lib/samba \
  -v $(pwd)/config:/etc/samba/external \
  --dns-search corp.example.com \
  --dns 192.168.3.222 \
  --add-host localdc.corp.example.com:192.168.3.222 \
  -h localdc \
  --name samba \
  --privileged \
  nowsci/samba-domain

ちょっと解説

DOMAIN の部分は ldap で言うところの dc に割り当てられます
あとで ldapsearch の動作確認コマンドも紹介しますがそこで使用します

DOMAINPASS は Administrator ユーザ用のパスワードになります
ADDC の場合少し特殊なパスワードポリシーがありいろいろと面倒なので INSECURELDAP を true にすることで回避しています

これが false のままだと

ldap_bind: Strong(er) authentication required (8)
        additional info: BindSimple: Transport encryption required.

というエラーが発生するのでそれの対処として設定します

各種ポートは必須になります
バインドするポートは作成した仮想ネットワーク上の IP を使ってバインドします

あとは特権を付与するのと必要なデータ領域のマウントをして起動してあげます

起動ログ

一応記載しておきます

Looking up IPv6 addresses
No IPv6 address will be assigned
Setting up share.ldb
Setting up secrets.ldb
Setting up the registry
Setting up the privileges database
Setting up idmap db
Setting up SAM db
Setting up sam.ldb partitions and settings
Setting up sam.ldb rootDSE
Pre-loading the Samba 4 and AD schema
Adding DomainDN: DC=corp,DC=example,DC=com
Adding configuration container
Setting up sam.ldb schema
Setting up sam.ldb configuration data
Setting up display specifiers
Modifying display specifiers
Adding users container
Modifying users container
Adding computers container
Modifying computers container
Setting up sam.ldb data
Setting up well known security principals
Setting up sam.ldb users and groups
Setting up self join
Adding DNS accounts
Creating CN=MicrosoftDNS,CN=System,DC=corp,DC=example,DC=com
Creating DomainDnsZones and ForestDnsZones partitions
Populating DomainDnsZones and ForestDnsZones partitions
Setting up sam.ldb rootDSE marking as synchronized
Fixing provision GUIDs
A Kerberos configuration suitable for Samba 4 has been generated at /var/lib/samba/private/krb5.conf
Setting up fake yp server settings
Once the above files are installed, your Samba4 server will be ready to use
Server Role:           active directory domain controller
Hostname:              localdc
NetBIOS Domain:        CORP
DNS Domain:            corp.example.com
DOMAIN SID:            S-1-5-21-3454798468-3565208184-955098804
/usr/lib/python2.7/dist-packages/supervisor/options.py:297: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  'Supervisord is running as root and it is searching '
2023-02-08 09:00:30,600 CRIT Supervisor running as root (no user in config file)
2023-02-08 09:00:30,600 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2023-02-08 09:00:30,608 INFO RPC interface 'supervisor' initialized
2023-02-08 09:00:30,608 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2023-02-08 09:00:30,608 INFO supervisord started with pid 17
2023-02-08 09:00:31,611 INFO spawned: 'samba' with pid 20
2023-02-08 09:00:32,796 INFO success: samba entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

動作確認

ldapsearch を使って ADDC にアクセスできるか確認します

LDAPTLS_REQCERT=never ldapsearch -x -b "dc=corp,dc=example,dc=com" -H ldap://192.168.3.222 -D "CN=Administrator,CN=Users,DC=CORP,DC=EXAMPLE,DC=COM" -w "yourAdminPassword"

とりあえずこれでいろいろと ADDC 内のエントリが検索できるのが確認できるかなと思います

自分が試した感じだと numResponses で 265 返却されました

LDAPTLS_REQCERT=never はなくても動作するかもしれません

最後に

Ubuntu に ADDC を構築してみました
今回は docker イメージを使用したので内部的に構成など詳しいことを気にせずサクっと構築しました
検証などではこのような方法で全然問題ないですが実際に運用する場合に理解を深めるためにも一から手動で構築してみるのもいいかなと思います

Tips

仮想ネットワークを作成しないで既存のネットワーク上にデプロイすることもできます

既存のネットワーク上ですでに bind9 などが動作している場合はそちらに Forward するような設定にしても OK です

例えば既存のネットワークである 10.100.xxx.xxx という IP アドレス対して動作させたい場合は以下のようになります

10.100.xxx.xxx ではすでに bind9 が動作しているのでそちらに forward するのと ADDC では 53 ポートを EXPOSE しないようにします

docker run -t -i \
  -e "DOMAIN=CORP.EXAMPLE.COM" \
  -e "DOMAINPASS=xxx" \
  -e "DNSFORWARDER=10.100.xxx.xxx" \
  -e "HOSTIP=10.100.xxx.xxx" \
  -e "INSECURELDAP=true" \
  -p 88:88 \
  -p 88:88/udp \
  -p 135:135 \
  -p 137-138:137-138/udp \
  -p 139:139 \
  -p 389:389 \
  -p 389:389/udp \
  -p 445:445 \
  -p 464:464 \
  -p 464:464/udp \
  -p 636:636 \
  -p 1024-1044:1024-1044 \
  -p 3268-3269:3268-3269 \
  -v /etc/localtime:/etc/localtime:ro \
  -v $(pwd)/data/:/var/lib/samba \
  -v $(pwd)/config:/etc/samba/external \
  --dns-search corp.example.com \
  --dns 10.100.xxx.xxx \
  --add-host localdc.corp.example.com:10.100.xxx.xxx \
  -h localdc \
  --name samba \
  --privileged \
  nowsci/samba-domain

参考サイト

2023年2月13日月曜日

Jinja2で変数を動的に作成して参照する方法

Jinja2で変数を動的に作成して参照する方法

概要

テンプレート内で参照したい変数名を動的に生成しその変数名の値を参照する方法を紹介します
わざわざ配列に set しなして参照する必要はありません

環境

  • macOS 11.7.3
  • Python 3.10.2
  • jinja2 3.1.2

サンプルコード

  • vim app.py
from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('test.tpl')
data = {
    'name': 'hawksnowlog',
    'items': ['blog', 'twitter', 'youtube'],
    'lang1': 'ruby',
    'lang2': 'python',
}
disp_text = template.render(data, data=data)
print(disp_text)
  • vim test.tpl
String
{{ name }}
{% for i in range(1, 3) -%}
* {{ data.get('lang'~i) }}
{% endfor %}

List
{% for item in items -%}
* {{ item }}
{% endfor %}

ポイント

  • render の際にキーワード引数としてのデータと位置引数としてのデータを渡します
    • キーワード引数として渡したデータはテンプレート内で data として参照できます
    • 位置引数として渡したデータはテンプレート内では key-value で展開され、key 名で値を参照できます
  • テンプレート内では動的変数を使って取得したい値はキーワード引数から参照します
    • その際に get メソッドを使いキーワードの引数のキーから取得します
    • キーの情報を動的に生成することで実現しています
    • 動的に生成するキーはチルダでつなぐことでキー情報というということを明示しています

できない方法

  • vim test.tpl
String
{{ name }}
{% for i in range(1, 3) -%}
* {{ lang~i }}
{% endfor %}

List
{% for item in items -%}
* {{ item }}
{% endfor %}

こんな感じで lang を直接参照しようとしても参照できないのでキーワード引数経由で参照しましょう

2023年2月10日金曜日

macOS で ApacheDirectoryStudio をインストールする方法

macOS で ApacheDirectoryStudio をインストールする方法

概要

Java がないと動かないのがポイントです

環境

  • macOS 11.7.3
  • java 19.0.2
  • Apache Directory Studio 2.0.0

Java のインストール

  • brew install java
  • echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc

ApacheDirectoryStudio のインストール

  • brew install --cask apache-directory-studio

起動

  • cd /Applications
  • open -a ApacheDirectoryStudio

ポイント

Finder から起動しようとしても java が古いので起動しません

ターミナルであれば Homebrew でインストールした最新の java が使えるのでターミナルから起動してあげましょう

2023年2月9日木曜日

Gitlab + ldap(tlsあり)設定メモ

Gitlab + ldap(tlsあり)設定メモ

概要

過去にTLSなしのLDAPと連携する方法を紹介しました

TLS 版も確認したのでメモがてら記載しておきます

ちなみに TLS + LDAP の構築方法はこちらです

gitlab.rb

gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = {
  'main' => {
    'label' => 'login',
    'host' => 'your.ldap.server.com',
    'port' => 1636,
    'uid' => 'uid',
    'encryption' => 'simple_tls',
    'verify_certificates' => true,
    'bind_dn' => 'cn=admin,dc=example,dc=org',
    'password' => 'xxx',
    'timeout' => 60,
    'active_directory' => false,
    'allow_username_or_email_login' => false,
    'block_auto_created_users' => false,
    'base' => 'dc=example,dc=org',
    'user_filter' => '',
    'lowercase_usernames' => false,
    'attributes' => {
      'username' => ['uid', 'userId', 'sAMAccountName'],
      'email' => ['mail', 'email', 'userPrincipalName'],
      'name' => 'uid',
      'first_name' => '',
      'last_name' => '',
    },
  }
}

start_tls だとエラーになる

gitlab

Could not authenticate you from Ldapmain because "No start tls result".

openldap

63e1d4cd.1b38e0da 0x7fbaf180c700 conn=1014 fd=14 ACCEPT from IP=xxx.xxx.xxx.xxx:33202 (IP=0.0.0.0:1636)
63e1d4cd.1b3b7769 0x7fbaf0d0a700 TLS: can't accept: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.
63e1d4cd.1b3e00d9 0x7fbaf0d0a700 conn=1014 fd=14 closed (TLS negotiation failure)

Openldap の場合は素直に simple_tls を使うのがいいのかもしれません

2023年2月8日水曜日

openldap サーバで tls を設定する方法

openldap サーバで tls を設定する方法

概要

前回 bitnami の openldap イメージで ldap サーバを構築してみました

今回は TLS 設定行ってみます

環境

  • Ubuntu 18.04
  • docker 20.10.7
  • bitnami/openldap 2.6.3

事前準備

  • ドメインの取得
  • A レコードの登録
  • A レコードの FQDN に対応した証明書の取得

は事前に済ませておいてください
ワイルドカード証明書があればそれでも OK です

今回証明書は certs 配下にデータを配置するディレクトリは data 配下とします

TLS + openldap の構築

コマンドは以下の通りです

docker run --name openldap -d \
    -v $(pwd)/certs:/opt/bitnami/openldap/certs \
    -v $(pwd)/data:/bitnami/openldap/ \
    -e ALLOW_EMPTY_PASSWORD=yes \
    -e LDAP_ENABLE_TLS=yes \
    -e LDAP_TLS_CERT_FILE=/opt/bitnami/openldap/certs/server.crt \
    -e LDAP_TLS_KEY_FILE=/opt/bitnami/openldap/certs/server.key \
    -e LDAP_TLS_CA_FILE=/opt/bitnami/openldap/certs/ca.crt \
    -p 1636:1636 \
    bitnami/openldap:latest

ちょっと解説

data ディレクトリは

  • mkdir data
  • chmod -R 777 data

しておきます
777 は「mkdir: cannot create directory ‘/bitnami/openldap/data’: Permission denied」対策です

ldapsearch で指定するホスト名は登録した FQDN でアクセスすることになるので 1636 ポートは外部からアクセスできるようにしておきます

証明書と鍵、CAファイルは指定が必須になります
証明書に CA 証明書の情報も記載されている場合はこちらの記事を参考に分割してください

動作確認

  • ldapsearch -x -H ldaps://your.ldap-server.com:1636 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w adminpassword

TLS である ldaps プロトコルの指定と 1636 ポートを指定します

これで検索結果が返却されれば OK です

トラブルシューティング

「-d 1」というオプションを付与すればデバッグ表示できます

  • ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

TLS の場合サーバ証明書のホスト名とアクセスするホスト名が同一でなければなりません
例えば ldaps://localhost:1636 などとすると上記のエラーになります

  • tls_write: want=31 error=Bad file descriptor

これは正常に検索結果が返ってきているにも関わらずデバッグ表示すると最後に表示されているエラーでした
基本は無視で問題ないかなと思います

最後に

Openldap で TLS を設定する方法を紹介しました
今回は docker から構築しましたが slapd を使った場合でも同じようなオプションが slapd.conf にあるのでそれを編集すれば有効にできると思います

ちなみに slapd.conf の場所はコンテナ内にはなくすべて ldif ファイルで管理されています

  • docker exec openldap slapcat -F /opt/bitnami/openldap/etc/slapd.d
  • sudo cat data/slapd.d/cn\=config.ldif

2023年2月7日火曜日

fullchain な証明書をサーバ証明書とCA証明書に分割する方法

fullchain な証明書をサーバ証明書とCA証明書に分割する方法

概要

nginx などはサーバ証明とCA証明書 (or 中間CA証明書) を結合して配置することができます
ただミドルウェアやツールによってはサーバ証明書とCA証明書は別に分けて配置しなければいけない場合があります

そんな場合に結合されたサーバ証明書を分割する方法を紹介します

環境

  • Ubuntu 18.04
  • openssl 1.1.1 11

サーバ証明書とCA証明書の順番を確認する

コマンドで確認できます
基本的に結合されている証明書は単純に複数の証明書が文字列で順番に結合されているだけです

ただ普通に見てもそれがどの証明書かわからないので openssl コマンドで確認します

  • openssl verify -show_chain --untrusted fullchain.pem fullchain.pem

で以下のような結果になれば OK です
以下の場合は上から順番にサーバ証明書CA証明書、中間CA証明書になります

fullchain.pem: OK
Chain:
depth=0: CN = *.myserver.com (untrusted)
depth=1: C = US, O = Let's Encrypt, CN = R3 (untrusted)
depth=2: C = US, O = Internet Security Research Group, CN = ISRG Root X1

分割する

あとは fullchain.pem を分割すれば OK です   「BEGIN CERTICATE」と「END CERTIFICATE」でひとかたまりなので最初の塊を server.crt として保存しあとの 2 つの塊を ca.crt として保存すれば OK です

手動で実施しても OK ですし適当なスクリプトを作成しても OK です

気をつけなければいけないのは必ず openssl コマンドで確認した順番と証明書の種類を意識して分割してください

サーバ証明書は基本一つになりCA関連の証明書は複数あります

2023年2月3日金曜日

bitnami の openldap サーバで ldap サーバを構築する

bitnami の openldap サーバで ldap サーバを構築する

概要

前回 ldap サーバを docker で構築してみました
今回は別イメージでも構築したので方法を紹介します

環境

  • Ubuntu 18.04
  • docker 20.10.7
  • bitnami/openldap 2.6.3

起動

  • docker run -d --name openldap bitnami/openldap:latest

少し説明

いくつかの値はデフォルトで設定されているので今回はそれを使います

  • dc のデフォルトは dc=example,dc=org
  • admin ユーザのデフォルトパスワードは「adminpassword」
  • デフォルトのポートは 1389

になっているのでこれらを使って動作確認します
上記のパラメータやこれら以外のパラメータは環境変数で設定可能です

検索

  • docker exec openldap ldapsearch -x -H ldap://localhost:1389 -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w adminpassword

ユーザ追加

  • vim hawk.ldif
dn: uid=hawk,dc=example,dc=org
uid: hawk
cn: hawk
sn: snowlog
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
loginShell: /bin/bash
homeDirectory: /home/hawk
uidNumber: 1000
gidNumber: 1000
userPassword: {SSHA}eSe6XqKkf4t7jgcfQYdG73L7u2xtWqib
mail: hawk@example.org
gecos: hawksnowlog

userPassword は slappasswd コマンドで生成するのがおすすめです

  • docker cp hawk.ldif openldap:/bitnami/openldap/data/hawk.ldif
  • docker exec openldap ldapadd -x -H ldap://localhost:1389 -D "cn=admin,dc=example,dc=org" -w adminpassword -f /bitnami/openldap/data/hawk.ldif

=> adding new entry "uid=hawk,dc=example,dc=org"

先程の検索コマンドで hawk ユーザが追加されていることを確認できれば OK です

最後に

次回は SSL を使った接続をしてみたいと思います

参考サイト

2023年2月1日水曜日

emacsでコピーした情報の履歴を確認する方法

emacsでコピーした情報の履歴を確認する方法

概要

Ctrl-w や Meta-w などでコピーした情報は kill-ring という配列に保存されます

環境

  • macOS 11.7.3
  • emacs 28.1

コマンド

  • helm-show-kill-ring

で一覧で表示されます
あと貼り付けたい行でエンターすれば貼り付けできます

もしくは直接 kill-ring から貼り付ける場合は

  • yank-from-kill-ring

を使います