Sourcegraph Docker安装和配置Azure AD登录

Sourcegraph

暂时用systemd来管理Docker service。因为我们要用Nginx来做反代,所有端口都监听本地即可。

[Unit]
Description=Sourcegraph
Requires=docker.service
Conflicts=systemd-resolved.service,dnsdist.service

[Service]
ExecStart=/usr/bin/docker run --name=sourcegraph --publish 127.0.0.1:7080:7080 --publish 127.0.0.1:2633:2633 --rm --volume /etc/sourcegraph:/etc/sourcegraph --volume /var/lib/sourcegraph/data:/var/opt/sourcegraph sourcegraph/server:3.3.5
ExecStop=/usr/bin/docker stop sourcegraph
ExecReload=/usr/bin/docker restart sourcegraph
TimeoutStartSec=infinity

[Install]
WantedBy=multi-user.target

Nginx SSL卸载

证书签发的问题就不细讲了,以certbot自动签发为例。涉及的文件参见oh-my-nginx

# 主站
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name sourcegraph.example.com;

    ssl_certificate     /etc/letsencrypt/live/sourcegraph.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sourcegraph.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:7080;
        include conf.d/templates/proxy-default.conf;
        include conf.d/templates/transparent-proxy.conf;
    }

    include conf.d/templates/ssl.conf;
    include conf.d/templates/performance.conf;
    include conf.d/templates/security.conf;
}

# 管理控制台
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name sourcegraph-mgmt-console.example.com;

    ssl_certificate     /etc/letsencrypt/live/sourcegraph-mgmt-console.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sourcegraph-mgmt-console.example.com/privkey.pem;
    
    location / {
        proxy_pass https://127.0.0.1:2633;
        include conf.d/templates/proxy-default.conf;
        include conf.d/templates/transparent-proxy.conf;
    }

    include conf.d/templates/ssl.conf;
    include conf.d/templates/performance.conf;
    include conf.d/templates/security.conf;
}

创建管理员

打开sourcegraph.example.com,创建一个管理员账号。如果你之后想合并这个账号和Azure AD账号,可以使用你的sAMAccountName作为用户名,并且添加一个userPrincipleName作为邮箱地址。

设置Azure AD登录

那这里我们还是用OpenID Connect登录流程。首先去Azure AD创建新应用程序,callback URL填写:

  • https://sourcegraph.example.com/.auth/callback

拿到:

  • tenant ID
  • client ID
  • client secret

然后打开Sourcegraph的管理控制台(用户名随便填,密码在第一次启动的时候log会打出来),填入:

{
  "externalURL": "https://sourcegraph.example.com",
  "auth.providers": [
    {
      "type": "builtin",
      "allowSignup": false
    },
    {
      "type": "openidconnect",
      "displayName": "Azure AD",
      "issuer": "https://login.microsoftonline.com/{tenant_id}/v2.0",
      "clientID": "{client_id}",
      "clientSecret": "{client_secret}"
    }
  ],
}

这里需要注意的是externalURL要准确填写。完成以后重启一下Sourcegraph以使externalURL生效。

添加Azure DevOps的Git repo

在External Services里面添加一个Single Git repositories,填入:

{
  "url": "https://{org_name}:{your_access_token}@dev.azure.com/{org_name}/",
  "repos": [
    "{project_name}/_git/{repo_name}"
  ]
}

注意Sourcegraph目前不支持project name中出现空格,详见sourcegraph/issues/2867

向ASA导入证书

准备一个私钥(.pem)和对应的证书(.crt)文件。注意证书里面只能有私钥对应的那个证书,不应该有证书链。

先用OpenSSL把它转成PKCS#12格式。

openssl pkcs12 -export -out asa.example.com.pfx -inkey asa.example.com.pem -in asa.example.com.crt

然后Base64一下。

openssl base64 -in asa.example.com.pfx -out asa.example.com.pfx.base64

导入ASA:

Type help or '?' for a list of available commands.
asa> enable
Password: 
asa# configure terminal
asa(config)# crypto ca import 证书名 pkcs12 密码
Enter the base 64 encoded pkcs12.
End with the word "quit" on a line by itself:
<粘贴 base64 过的文件>
quit
INFO: Import PKCS12 operation completed successfully

换上新的证书:

asa(config)# ssl trust-point newcert inside 
asa(config)# ssl trust-point newcert outside
asa(config)# no crypto ikev2 remote-access trustpoint oldcert
asa(config)# crypto ikev2 remote-access trustpoint newcert

删掉原来的证书:

asa(config)# no crypto ca trustpoint oldcert

 

在systemd unit里执行需要TTY的程序

总有那么几个程序一定要用ncurses在终端画窗口,即使它完全可以在后台运行。这时候我们就需要欺骗它一下,假装它在一个TTY里面运行。有两点需要设置:

  • 设置环境变量TERM=linux
  • 用script程序来假装外面有个TTY

例如一个简单的rtorrent (<0.9.7) systemd unit设置:

# cat [email protected] 
[Unit]
Description=rTorrent
After=network-online.target

[Service]
User=%i
Environment=TERM=linux
ExecStartPre=/bin/sh -c "/usr/bin/mkdir -p \"$HOME/.local/share/rtorrent/session\""
ExecStart=/usr/bin/script -qefc '/usr/bin/rtorrent -s $HOME/.local/share/rtorrent/session -o session=$HOME/.local/share/rtorrent/session' /dev/null
WorkingDirectory=~
Restart=on-failure

[Install]
WantedBy=multi-user.target

注:rtorrent 0.9.7开始可以用-o system.daemon.set=true,所以不需要这么麻烦:

# cat [email protected] 
[Unit]
Description=rTorrent
After=network-online.target

[Service]
User=%i
ExecStartPre=/bin/sh -c "/usr/bin/mkdir -p \"$HOME/.local/share/rtorrent/session\""
ExecStart=/bin/sh -c "/usr/bin/rtorrent -s $HOME/.local/share/rtorrent/session -o session=$HOME/.local/share/rtorrent/session -o system.daemon.set=true"
WorkingDirectory=~
Restart=on-failure

[Install]
WantedBy=multi-user.target