持续集成系统搭建(一) Jenkins + Redmine + CAS + github OAuth2 实现 SSO

Posted by Joseph Han on 2016-11-08

title: 持续集成系统搭建(一) Jenkins + Redmine + CAS + github OAuth2 实现 SSO
tag:

  • CI
  • SSO
  • OAuth2
  • Jenkins
  • Redmine
  • Linux
    date: 2016-11-08 18:14:08
    tags:

安装Jetty服务器

$ wget http://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.13.v20161014/jetty-distribution-9.3.13.v20161014.tar.gz

解压到 /opt/eclipse/jetty

$ ln -s /opt/eclipse/jetty/bin/jetty.sh /etc/init.d/jetty

新建 /etc/default/jetty
加入

JAVA_HOME=/usr/bin/java
JETTY_HOME=/opt/eclipse/jetty

修改 /opt/eclipse/jetty/start.ini 中的配置

jetty.http.host=127.0.0.1 //修改绑定ip为本地
jetty.http.port=8088 //修改端口

将jetty加入系统启动服务

$ update-rc.d jetty defaults

配置nginx服务器,实现代理

在 /etc/nginx/site-enable 中增加一个配置 ci
内容如下

server {

  listen 80;  
  listen [::]:80;  
  server_name ci.joseph-han.net;  
  location /jenkins/ {  
      proxy_pass      http://127.0.0.1:8088/jenkins/;  
      proxy_redirect  off;  
      proxy_set_header        Host            $host;  
      proxy_set_header        X-Real-IP       $remote_addr;  
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;  
  }  

}

以管理员身份登陆Jenkins,设置当前服务器为Master,设置从节点数量为5个

VPS内核太低,不支持docker,等带自己的服务器环境搭建完成再上Jenkins集群 :(

配置docker,实现swarm集群

配置swarm master节点

配置swarm salve节点

##安装Redmine

  1. 在mysql创建redmine数据库
  2. 为Nginx安装Phusion Passenger Passenger 官网安装指导

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list’
sudo apt-get update
sudo apt-get install -y nginx-extras passenger

修改/etc/nginx/nginx.conf

include /etc/nginx/passenger.conf;
sudo service nginx restart

验证

sudo /usr/bin/passenger-config validate-install
sudo /usr/sbin/passenger-memory-stats

  1. 配置 nginx

vim /etc/nginx/sites-enable/ci

    location ~ ^/redmine(/.*|$) {  
       alias /opt/CI/redmine/public$1;  # <-- be sure to point to 'public'!  
       passenger_base_uri /redmine;  
       passenger_app_root /opt/CI/redmine;  
       passenger_document_root /opt/CI/redmine/public;  
       passenger_enabled on;  
   }  
  1. 下载redmine

cd /opt/CI
wget http://www.redmine.org/releases/redmine-3.3.1.tar.gz
tar vxf redmine-3.3.1.tar.gz
ln -s /opt/CI/redmine-3.3.1 ./redmine
chown -R www-data.www-data /opt/CI

  1. 配置redmine

cd /opt/CI/redmine/config
cp configuration.yml.example configuration.yml
cp database.yml.example database.yml

配置db

  1. 安装ruby依赖

gem install bundler
apt install libroot-bindings-ruby-dev
apt install libmysqlclient-dev
apt install libmagickwand-dev
bundle install --without development test

  1. 生成tocken和数据表:

bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake redmine:load_default_data

安装CAS

  1. 下载cas并编译cas-gradle-overlay-template
    注意为了使用github代理登陆一定要添加依赖 Reference: Delegate Authentication

vim ~/cas-gradle-overlay-template/cas/build.gradle

1
2
3
4
5
6
7
8
9
dependencies {
compile "org.apereo.cas:cas-server-webapp:${project.'cas.version'}@war"
compile "org.apereo.cas:cas-server-support-pac4j-webflow:${project.'cas.version'}" //新增 for 5.0
}

dependencies {
compile "org.jasig.cas:cas-server-webapp:${project.'cas.version'}@war"
compile "org.jasig.cas:cas-server-support-pac4j-webflow:${project.'cas.version'}" //新增 for 4.2:
}

cd ~/cas-gradle-overlay-template;./gradlew clean build

//到~/cas-gradle-overlay-template/cas/build/libs下把cas.war拷贝到/opt/CI/
将~/cas-gradle-overlay-template/etc/cas/ 下的配置文件解压到/etc/cas下

  1. 配置nginx服务器,实现ssl代理
    生成服务器ssl证书
    注意:名字一定要是服务器域名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
证书文件生成:

一. 服务器端

1. 生成服务器端 私钥(key文件):
openssl genrsa -des3 -out server.key 1024
运行时会提示输入密码,此密码用于加密key文件(参数des3是加密算法,也可以选用其他安全的算法),以后每当需读取此文件(通过openssl提供的命令或API)都需输入口令,如果不要口令,则去除口令:
mv server.key server.origin.key
openssl rsa -in server.origin.key -out server.key
2. 生成服务器端证书签名请求文件(csr文件):
openssl req -new -key server.key -out server.csr
生成Certificate Signing Request(CSR),生成的csr文件交给CA签名后形成服务端自己的证书。屏幕上将有提示,依照其 提示一步一步输入要求的个人信息即可(如:Country,province,city,company等)。

二. 客户端

1. 生成客户端私钥(key文件):
openssl genrsa -des3 -out client.key 1024
2. 生成客户端证书签名请求文件(csr文件):
openssl req -new -key client.key -out client.csr

三. 生成CA证书文件

#server.csr 与 client.csr文件必须有CA的签名才可形成证书。
cd /tmp/create_key/ca
1. 首先生成CA的key文件:
openssl genrsa -des3 -out ca.key 1024
2. 生成CA自签名证书:
openssl req -new -x509 -key ca.key -out ca.crt -days 3650
可以加证书过期时间选项 "-days 3650".

四. 利用CA证书进行签名

openssl ca -in ../server.csr -out ../server.crt -cert ca.crt -keyfile ca.key
openssl ca -in ../client.csr -out ../client.crt -cert ca.crt -keyfile ca.key
这两条执行的时候因为没有指定openssl.cnf 会报错,不过没关系,我们用默认的 /etc/pki/tls/openssl.cnf 就可以。
不过用默认的时候需要先执行下面两行:
touch /etc/pki/CA/index.txt
echo 00 > /etc/pki/CA/serial

//3. 配置CAS Reference: CAS Properties

// >vim /opt/CI/cas/WEB-INF/classes/application.properties

  1. 配置cas增加github代理认证

vim /opt/CI/cas/WEB-INF/spring-configuration/applicationContext.xml

1
2
3
4
5
<bean id="github" class="org.pac4j.oauth.client.GitHubClient">
<property name="key" value="15a52a6de46737xxxxx" />
<property name="secret" value="f938abe21612a652ec41c767383fe3848xxxxxx" />
<property name="callbackUrl" value="https://sso.joseph-han.net/cas/" />
</bean>

修改service id,使http的客户端也可以访问https的服务器

vim /opt/CI/cas/WEB-INF/classes/services/Apereo-10000002.json

1
"serviceId" : "^http.*",  //原来是https://

事先生成下面要用的密钥 Reference: secret key tool

vim /opt/CI/cas/WEB-INF/cas.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# The encryption secret key. By default, must be a octet string of size 256.
tgc.encryption.key=FPWBWR2r7GKldTr5WTeQPFEJHV7Xq0Uel0VLsIeMZPE
# The signing secret key. By default, must be a octet string of size 512.
tgc.signing.key=MijU8ew5hYkGjHVQWMRReLilGTUUqlHex-P84ceWajaYjvuASNgvYaLUWYCnCA0fWj_vXifyfImnHawdouBXYg
# Decides whether SSO cookie should be created only under secure connections.
tgc.secure=true
# The expiration value of the SSO cookie
tgc.maxAge=-1
# The name of the SSO cookie
tgc.name=CAS_TGC
# The path to which the SSO cookie will be scoped
tgc.path=/cas
# The expiration value of the SSO cookie for long-term authentications
tgc.remember.me.maxAge=1209600
# Decides whether SSO Warning cookie should be created only under secure connections.
warn.cookie.secure=true
# The expiration value of the SSO Warning cookie
warn.cookie.maxAge=-1
# The name of the SSO Warning cookie
warn.cookie.name=CASPRIVACY
# The path to which the SSO Warning cookie will be scoped
warn.cookie.path=/cas
# Whether we should track the most recent session by keeping the latest service ticket
tgt.onlyTrackMostRecentSession = true
# Indicates whether an SSO session should be created for renewed authentication requests.
create.sso.renewed.authn=true
# Indicates whether an SSO session can be created if no service is present.
create.sso.missing.service=true
# Authentication delegation using pac4j
#一定要设置fals否则返回的id带有GithubProf#会影响jenkins生成的url
cas.pac4j.client.authn.typedidused=false

Redmine 关联 CAS

cd /opt/CI/redmine/plugins/
git clone https://github.com/joseph-bing-han/redmine_omniauth_cas.git
我fork了插件代码,增加了自动创建用户到db的逻辑
登陆管理页面配置正确cas域名即可

Jenkins 关联 CAS

登陆系统,在插件管理页面安装CAS plugins http://ci.joseph-han.net/jenkins/pluginManager/available
配置好cas域名,重启服务即可