STNSがDynamoDBやS3と連携できるようになり、LDAPをしゃべるようになった

社内のk8s移行を進めるに当たり、STNSもクラウドネイティブなアーキテクチャに対応した。対応した内容としては下記のとおりです。

  1. DyanmoDBをバックエンドとして利用可能になった
  2. Redisを利用したキャッシュを利用できるようになった
  3. S3に設定ファイルを置けるようになった
  4. stns-passwdでサーバ上のパスワードを変えられるようになった
  5. LDAPを利用したパスワード認証が可能になった

DyanmoDBをバックエンドとして利用可能になった

パスワード認証などに動的に変更可能なバックエンドが必要になり、旧来よりEtcdはサポートしておったのですが、DyanamoDBも追加しました。利用方法としてはDynamoDBの権限を持つAWSのクレデンシャルを環境変数に設定し、設定ファイルにモジュールの読み込みを記載するだけです。

ちなみに syncをTrueに設定すると、TomlファイルからDynamoDBにユーザー、グループ情報をSyncしてくれるのでTomlで管理しつつ、パスワードはDynamoDBで管理するというようなことができます。

$ export AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxx
$ export AWS_REGION=xxxxxxxxxxxxx

$ cat stns.conf
load_module = "mod_stns_dynamodb.so"

[modules.dynamodb]
sync = true

Redisを利用したキャッシュを利用できるようになった

DyanamoDBを利用する場合、レイテンシや課金が気になる場合もあると思うので、間にRedisをかませるようにしました。

こちらも設定はこれだけで動きます。

[redis]
host = "xxx.xxx.xxx.xxx"
port = 6379

認証が必要な場合は、 STNS_REDIS_PASSWORD を環境変数として設定してください。

S3に設定ファイルを置けるようになった

k8sで動作させるに当たり、設定ファイルをS3におけると便利だったので、実装しました。こちらは起動オプションから指定可能です。

$ export AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxx
$ export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxx
$ export AWS_REGION=xxxxxxxxxxxxx
$ stns --config s3://bukect_name/stns.conf server

stns-passwdでサーバ上のパスワードを変えられるようになった

DynamoDBやEtcdをバックエンドに利用した場合に、パスワード情報を変更することができます。

$ stns-passwd update -endpoint https://endpoint/v1 \
  -user $STNS_BASIC_AUTH_USER \
  -password $STNS_BASIC_AUTH_PASSWORD \
  <your_name>

上記の例はBasic認証が入っている例ですが、TLS認証についても対応しているので安心して利用できると思います。

LDAPを利用したパスワード認証が可能になった

STNSはLDAPの運用がしんどくて開発したのですが、未だにLDAPで認証を行うミドルウェアは多く、そういったミドルウェアとSTNSが組み合わせられるようにLDAPを喋れるようにしました。またCentOS4(まだあるんですかね?HAHAHA)などの古いOSをlibnss-stnsはサポートしていないので、そういったOSではlibnss-ldapを利用してSTNSを利用することができます。

起動コマンドでプロトコルを選択します。

$ stns --protocol ldap server

インターフェースとしてはSearchとBindをサポートしており、もちろんLDAPSも対応済みです。


$ ldapsearch -H ldaps://endpoint:636 \
  -x -LLL -D "cn=admin,dc=stns,dc=local" \
  -W -b "dc=stns,dc=local" "uid=example"
Enter LDAP Password:
dn: cn=shiro16,ou=pepabo,dc=stns,dc=local
cn: example
uid: example
givenName: example
ou: example_group
uidNumber: xxxxxxx
accountStatus: active
objectClass: posixAccount

シュッとk8sで動かす

最後に、ペパボでは下記のDeploymentを利用してk8s上で運用しています。そのまま貼っても問題ないくらいにk8sが抽象化してくれるのまじ便利ですね。

  • deployment.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stns
  labels:
    app: stns
spec:
  replicas: 2
  selector:
    matchLabels:
      app: stns
  template:
    metadata:
      labels:
        app: stns
    spec:
      containers:
      - name: stns-http
        image: stns/stns:latest
        command: ["stns", "--config", "/stns/stns.conf", "server"]
        livenessProbe:
          exec:
            command: ["curl", "-k", "https://localhost:1105"]
          initialDelaySeconds: 15
          periodSeconds: 20
        env:
          - name: STNS_BASIC_AUTH_USER
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: basic_user
          - name: STNS_BASIC_AUTH_PASSWORD
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: basic_password
          - name: AWS_ACCESS_KEY_ID
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: aws_access_key_id
          - name: AWS_SECRET_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: aws_secret_access_key
          - name: AWS_REGION
            value: ap-northeast-1
          - name: STNS_REDIS_PASSWORD
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: redis_password
          - name: STNS_LISTEN
            value: ":1105"
        volumeMounts:
        - name: stns-config
          mountPath: /stns
        - name: includes
          mountPath: /stns/conf.d
        - name: certs
          mountPath: /stns/certs
      - name: stns-ldap
        image: stns/stns:latest
        command: ["stns", "--config", "/stns/stns.conf", "--protocol", "ldap", "server"]
        livenessProbe:
          tcpSocket:
            port: 636
          initialDelaySeconds: 15
          periodSeconds: 20
        env:
          - name: AWS_ACCESS_KEY_ID
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: aws_access_key_id
          - name: AWS_SECRET_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: aws_secret_access_key
          - name: AWS_REGION
            value: ap-northeast-1
          - name: STNS_REDIS_PASSWORD
            valueFrom:
              secretKeyRef:
                name: stns-secret
                key: redis_password
          - name: STNS_LISTEN
            value: ":636"
        volumeMounts:
        - name: stns-config
          mountPath: /stns
        - name: includes
          mountPath: /stns/conf.d
        - name: certs
          mountPath: /stns/certs
      volumes:
      - name: stns-config
        configMap:
          name: stns-config
      - name: includes
        configMap:
          name: includes
      - name: certs
        secret:
          secretName: stns-secret
          items:
          - key: cert
            path: example.crt
          - key: key
            path: example.key

---
apiVersion: v1
kind: Service
metadata:
  name: stns
spec:
  type: LoadBalancer
  selector:
    app: stns
  ports:
    - port: 1105
      name: http
    - port: 636
      name: ldap
  • kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yml
configMapGenerator:
- files:
  - stns.conf
  name: stns-config
- files:
  - conf.d/group.conf
  - conf.d/group_from_ghe.conf
    - conf.d/user.conf
  - conf.d/user_from_ghe.conf
  name: includes
  • stns.conf
include = "/stns/conf.d/*conf"
load_module = "mod_stns_dynamodb.so"

[tls]
cert = "/stns/certs/example.crt"
key = "/stns/certs/example.key"

[groups.example]
id = 2000

[redis]
host = "xxx.xxx.xxx.xxx"
port = 6379

[modules.dynamodb]
sync = true

k8sとAWSに諸々を任せることで運用が超楽になったので、是非試していただけると嬉しいです。