前言
在老和山职业技术学院读书的时候就开始从事实验室的兼职网管,负责实验室的网络建设以及服务器的维护,也是时候写个文章把攒了这么多年的知识科普一下。
硬件
- portal: 登录服务器,也是终端用户唯一可以访问的机器
- core: 核心服务器,上面部署了ipa,jenkins,gitlab,jira,sungrid等服务
- grid00: 运算服务器1,用作sungrid的computing node
- grid01: 运算服务器2,用作sungrid的computing node
- netapp: 存储服务器,做芯片的一般就用netapp
网络配置
参考的网络拓扑如下
- 一个内网段 10.0.2.0/24 (用于服务器之间的通信)
- 一个外网IP 192.168.5.100 用于终端客户的访问
- 自定义域名: ic.X.com
系统安装
系统推荐用centos 7.9, 当然也可以用最新的centos 8 stream。在某些最新的server上面,硬件已经不支持centos 7了,所以只能装centos 8. 8和7的系统稍微在配置上稍微有一些差别。
安装的时候把一些开发者工具都给装上可以避免后续很多问题。
portal
对外的网卡 ext: ip 配置成 192.168.5.100
对内的网卡 int: ip 配置成 10.0.2.1
配置网卡的时候一些注意事项
- NetworkManager的影响: 如果是直接修改 /etc/sysconfig/network-scripts的方式进行配置的话,记得里面加一行 NM_CONTROLLED=no ,或者干脆就把NetworkManger卸载掉得了
- 网卡的名字: 默认的名字总是奇奇怪怪,早起的叫ethX,后来变成emX,如果是光口,名字可能叫做p1p2这种,这种名字可以在ifcfg-xx 里面进行修改
可以使用以下命令对网卡名字做动态修改
1
| ip link set old_device_name name new_device_name
|
如果是要静态修改的话需要对ifcfg-xx做以下修改
- 将ifcfg_old_name重命名为ifcfg_new_name
- 将文件里面的DEVICE和NAME修改为new_name
- HWADDR需要修改成网卡的真实地址
core
网卡 int: ip 配置成10.0.2.100
额外注意事项
- 该机器最后会当做flexlm的license server,有些license daemon是挑网卡名字的,比如TSMC的一定要求网卡的名字是eth 打头,所以请至少保留一块网卡地址用这个名字
- 如果有改MAC地址需求的,需要再ifcfg-xx 里面需要用HWADDR指定网卡之前的MAC地址,让后用MACADDR指明需要更改的MAC地址
grid00
网卡 int: ip 配置成 10.0.2.10
grid01
网卡 int: ip 配置成 10.0.2.12
netapp
取决于买的型号类型,一般需要配置业务口和管理口,后者仅用于管理功能,带宽需求不大。业务口的话推荐做链路聚合。
软件安装及配置
ssh 免密登录
首先产生密钥对
不用RSA的原因是RSA的密钥长,计算工作量大,而且安全性也不高。题外话,RSA512现在已经可以用普通计算机进行暴力破解了。
然后将公钥复制黏贴进对方机器的 .ssh/authorized_keys 即可,当然你也可以用以下命令进行自动拷贝
1
| ssh-copy-id -i eda25519.pub core
|
NTP
使用chrony
portal作为NTP server,提供定时服务给到10.0.2.0/24网段
1
2
3
4
5
6
7
8
9
10
11
12
| root@portal:~ #-> cat /etc/chrony.conf |grep -v '^#'
erver 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.0.2.0/24
local stratum 10
logdir /var/log/chrony
log measurements statistics tracking
|
其他服务器需要将upstream设置为portal
1
2
3
4
5
6
| root@grid00:~ #->cat /etc/chrony.conf|grep -v '^#'
server 10.0.2.1 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
|
IPA
这个是一个认证服务器,大家可能听说过nis,nisplus,yellowpage,ldap其实本质都是一个东西,只不过扩展性不一样。IPA的话其实底层走的还是ldap那一套,只不过集成了管理界面,对用户更加友好。
server安装
1
| ipa-server-install -N --domain-level 0 --allow-zone-overlap --idstart 2000
|
注意其中的idstart
,根据情况自己修改
安装过程中会提示admin password和directory manager的password
安装过程会提示上游DNS,填10.0.2.1
client安装
以grid00为例
1
| ipa-client-install --server=core.ic.X.com --domain=grid00.ic.X.com -N --enable-dns-updates --hostname=grid00.ic.X.com
|
SSL 证书
在IPA server的安装过程中,会将产生的root CA放在/root/cacert.p12下面,可以用
xca
导入进行管理,以后可以用这个root CA签名新的证书。导入过程中会提示你输入密码,这个密码就是安装过程中输入的admin password。
都已经2024年了,推荐所有的服务都上https
IPA的管理界面默认会占用80/443/8080/8443端口,请避免和其他服务冲突
windows电脑登录的时候会跳出一个认证框,这是因为windows支持kerbose login, 可以通过在 /etc/httpd/conf.d/ipa.conf 里面添加如下配置禁用
1
2
| GssapiSessionKey file:/etc/httpd/alias/ipasession.key
BrowserMatch Windows gssapi-no-negotiate
|
常见操作
增加一个DNS解析
如果你只是想增加一个DNS解析的话,可以使用下面的命令(将gitlab.ic.X.com解析成10.0.2.100)
1
| ipa dnsrecord-add ic.X.com. --name gitlab --a-rec 10.0.2.100
|
缓存刷新
刷新IPA缓存
刷新系统缓存
DNS 解析
在portal上面安装dnsmasq并指定上游,例如 114
修改所有机器的 /etc/resolv.conf
1
2
| search ic.X.com
nameserver 10.0.2.100
|
这里再次吐槽NetworkManager,默认是会去把这个文件给overwrite掉的,需要做一些额外处理。或者就像我一样,不管三七二十一,直接把NetworkManager给干了。
一个典型的查询场景如下所示,需要注意的是如果查询的域名位于ic.X.com,那直接在core就会返回查询结果。
sequenceDiagram
participant grid00
participant core
participant portal
participant public_dns
grid00 ->> core: DNS query for www.baidu.com
core ->> portal: forward the query
portal ->> public_dns: forward the query
public_dns ->> portal: query result for www.baidu.com
portal ->> core: query result for www.baidu.com
core ->> grid00: query result for www.baidu.com
netapp
将netapp的目录以NFS的方式挂载到各台机器上,建议挂载分区如下
- /proj: 项目相关的文件
- /tools: EDA工具
- /tmpdir: 临时目录,比如仿真文件等
- /home: 用户主目录
- /opt/sge: sungrid的共享目录,其实严格意义上来说只有SGE_CELL那个路径才需要共享,但是都共享了也没太大问题。直接用core分享也可以
需要注意的是netapp默认的nfs4版本会进行root_squash,导致root账号被映射成了nobody,解决办法是在挂载的时候选择用nfs3挂载
1
| 10.0.2.155:/home /home nfs defaults,async,nosuid,nodev,hard,intr,nfsvers=3,timeo=60,retrans=5 0 0
|
netapp如果要关系,需要使用以下命令,要防止主node被backup node给take over掉
1
| system node halt -node * -skip-lif-migration-before-shutdown true -ignore-quorum-warnings true -inhibit-takeover true
|
gcc
系统如果要安装多个gcc版本,建议下载源码解压之后用如下方式进行编译
1
2
3
4
| ./contrib/download_prerequisites
mkdir build && cd build
../configure --prefix=/tools/misc/gcc/xx.xx.xx --enable-checking=release --enable-languages=c,c++ --enable-threads=posix --disable-multilib --with-system-zlib
make -j64 && make install
|
版本之间的切换可以用
modules
进行管理。
sungrid
sungrid是一个开源的集群运算软件,在core上执行
1
| yum install -y jemalloc gridengine gridengine-execd gridengine-guiinst gridengine-qmaster gridengine-qmon
|
然后通过如下命令启动图形安装界面
1
| cd /opt/sge && ./start_gui_installer
|
gitlab
gitlab
是一个可以私有部署的程序员内部交友网站,主要的配置文件是/etc/gitlab/gitlab.rb。
最重要的数据文件推荐放在netapp的存储上面,备份文件建议放在core的本地存储上面,对应的配置如下
1
2
3
4
5
6
7
8
9
10
| git_data_dirs({
"default" => {
"path" => "/proj/git"
}
})
gitlab_rails['manage_backup_path'] = true
gitlab_rails['backup_path'] = "/data/backup/gitlab"
gitlab_rails['backup_gitaly_backup_path'] = "/opt/gitlab/embedded/bin/gitaly-backup"
gitlab_rails['backup_keep_time'] = 2592000
|
对gitlab.rb的内容进行更改之后,需要通过如下命令进行配置刷新
ssl
要将CA放到 /etc/gitlab/trusted-certs 下面
修改gitlab.rb,关键配置如下
1
2
3
4
| nginx['ssl_certificate'] = "/etc/ssl/ic.X.com/server.crt"
nginx['ssl_certificate_key'] = "/etc/ssl/ic.X.com/server.key"
external_url 'https://core.ic.X.com'
nginx['listen_port'] = 1024
|
可以通过下面的rewrite rule将
https://git.ic.X.com
重定向到
https://core.ic.X.com:1024
1
2
3
4
| root@core:~ #-> cat /etc/httpd/conf.d/gitlab-rewrite.conf
# VERSION 6 - DO NOT REMOVE THIS LINE
RewriteEngine on
RewriteRule ^/gitlab https://core.ic.X.com:1024 [L,R=301]
|
ldap
修改gitlab.rb.关键配置如下
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
| gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'LDAP',
'host' => 'core.ic.X.com',
'port' => 636,
'uid' => 'uid',
'bind_dn' => 'uid=dummy,cn=users,cn=accounts,dc=ic,dc=X,dc=com',
'base' => 'dc=ic,dc=X,dc=com',
'password' => 'password for dummy',
'encryption' => 'simple_tls',
'verify_certificates' => true,
'smartcard_auth' => false,
'active_directory' => false,
'allow_username_or_email_login' => true,
'lowercase_usernames' => false,
'block_auto_created_users' => false,
'user_filter' => 'memberOf=cn=staff,cn=groups,cn=accounts,dc=ic,dc=X,dc=com',
'attributes' => {
'username' => ['uid'],
'email' => ['Email'],
'name' => 'cn',
'first_name' => 'givenName',
'last_name' => 'sn'
},
## EE only
'group_base' => 'cn=groups,cn=accounts,dc=ic,dc=X,dc=com',
'admin_group' => '',
'sync_ssh_keys' => false
}
}
|
配置完之后可以用如下命令进行测试
1
| gitlab-rake gitlab:ladap:check
|
migration
可以用如下的方式进行迁移
- 进入旧文件夹,git remote 解除远端reposity的绑定
- git remote 添加新远端repository
- git push
jenkins
ssl
jenkins用的是java那一套,所以ssl的支持稍微麻烦一点。
CA: update-ca-trust 本身就已经产生了java需要的CA,具体的路径是 /etc/pki/ca-trust/extracted/java/cacerts
https证书: 用xca生成p12格式的证书(.pfx),然后用如下命令转换,其中changeit是证书导出的时候设置的密码
1
| keytool -importkeystore -srcstorepass changeit -deststorepass changeit -srckeystore ssl.pfx -srcstoretype pkcs12 -destkeystore jenkins.jks -deststoretype JKS
|
修改配置文件 /usr/lib/systemd/system/jenkins.service,关键配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| root@core:~ #-> cat /usr/lib/systemd/system/jenkins.service|grep -v '^#'
#jenkins is picky on java version, must use version 17
Environment="JAVA_HOME=/usr/java/jdk-17.0.5"
Environment="JENKINS_JAVA_CMD=/usr/java/jdk-17.0.5/bin/java"
#load the CA so we can use ldaps
Environment="JAVA_OPTS=-Djava.awt.headless=true -Djavax.net.ssl.trustStore=/home/jenkins/config/cacerts -Djavax.net.ssl.trustStorePassword=changeit"
#turn off http and enable https
Environment="JENKINS_PORT=-1"
Environment="JENKINS_HTTPS_LISTEN_ADDRESS=10.0.2.100"
Environment="JENKINS_HTTPS_PORT=8888"
#specify the https ceritificate
Environment="JENKINS_HTTPS_KEYSTORE=/home/jenkins/config/jenkins.jks"
Environment="JENKINS_HTTPS_KEYSTORE_PASSWORD=changeit"
[Install]
WantedBy=multi-user.target
|
ldap
需要安装ldap插件,/home/jenkins/config.xml 里面的关键配置信息如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| <securityRealm class="hudson.security.LDAPSecurityRealm" plugin="ldap@682.v7b_544c9d1512">
<disableMailAddressResolver>false</disableMailAddressResolver>
<configurations>
<jenkins.security.plugins.ldap.LDAPConfiguration>
<server>ldaps://core.ic.X.com</server>
<rootDN>dc=ic,dc=X,dc=com</rootDN>
<inhibitInferRootDN>false</inhibitInferRootDN>
<userSearchBase>cn=users,cn=accounts</userSearchBase>
<userSearch>uid={0}</userSearch>
<groupMembershipStrategy class="jenkins.security.plugins.ldap.FromGroupSearchLDAPGroupMembershipStrategy">
<filter></filter>
</groupMembershipStrategy>
<managerDN>uid=dummy,cn=users,cn=accounts,dc=ic,dc=X,dc=com</managerDN>
<managerPasswordSecret>{dummy_password_hash}</managerPasswordSecret>
<displayNameAttributeName>displayname</displayNameAttributeName>
<mailAddressAttributeName>mail</mailAddressAttributeName>
<ignoreIfUnavailable>false</ignoreIfUnavailable>
</jenkins.security.plugins.ldap.LDAPConfiguration>
</configurations>
<userIdStrategy class="jenkins.model.IdStrategy$CaseInsensitive"/>
<groupIdStrategy class="jenkins.model.IdStrategy$CaseInsensitive"/>
<disableRolePrefixing>true</disableRolePrefixing>
</securityRealm>
|
如果因为某些原因导致更改完了登录不了jenkins ( 比如权限忘记配置了),只需要将下面的配置从true改为false即可
1
| <useSecurity>true</useSecurity>
|
ETX
这是一个服务器登录软件。推荐
EXT
,吊打一切牛鬼蛇神,主要优势有以下几个
- 只用开放一个端口即可,这样就方便进行管理。vnc这种每个用户都开一个端口的方式一是不方便管理,而是有漏洞,用户要进行脱库操作很容易。
- 可以对上传下载权限进行单独管理,一般只允许上传,不允许下载
- 可以限制从服务器到本地复制黏贴的字符个数,有效的防止了用户通过CTRL+C CTRL+V 的方式拷贝代码到本地
- 集成ldap认证,可对用户登录以及可见的profile做限制
当然他的缺点也是显而易见的,那就是需要花钱购买。这公司的销售人员也是非常了解国情,默认都是提供买断的license服务,一次购买,终身可用,然后单个license的价格还是不便宜。
server
建议安装在core上面,然后通过端口映射的方式映射到portal的8443端口
node
建议安装在portal上面,默认端口是5510
添加node的时候选择10.0.2.1,端口5510,然后再client IP里面进行重映射,比如192.168.5.100:5510
ssl
如果要增加ssl支持,需要修改 $INSTALL_DIR/data/ssl 里面的 server.key 和server.crt. 可以用前文提到的xca工具生成,懒人的话建议生成通配符证书即可。
另外其实在linux上面做ETX的多开很容易,文件夹复制黏贴改个名字就行了。Windows node 复制黏贴比较麻烦,暂时还没有花精力去搞。至于为何要多开?那当然是解决license个数不足的问题了。
flexlm
几乎所有的eda工具都是用flexlm来管理的,这个和谐方式也是各式各样。有一些注意事项
- 允许在同一个端口上起多个vendor的license daemon,比如你可以把不同家的license文件里面的端口都改成一样的,然后lmgrd一起启动
- 一些和谐版的license daemon会有相互打架的情况,所以1的前提就不成立了
- 有些vendor daemon对网卡名字有特别要求,一定要求是 eth 开头,比如TSMC
- license文件可以进行复制操作,比如你只买了10个正版license,如何扩展成100个,土鳖一点的方法就是用虚拟机多开,修改MAC地址。但是其实不用这么麻烦的,你在一台机器上也有办法实现开N个相同的vendor daemon的。
由于可能不是那么众所周知的原因,宝岛台湾的一些工具是不使用flexlm管理的。个人推测一方面是成本考虑,另一方面是因为他们知道flexlm的license很容易被和谐,又不像大厂可以承受被破解的代价,所以就自己开发了一套软件授权管理工具。
mirror
在core上面设置centos的mirror,portal通过rsync的方式将外部的mirror同步到core上
一个简单的用perl写的同步脚本如下
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
| #!/usr/bin/perl
use strict;
use warnings;
my $lock_file = "/run/lock/subsys/repo_rsync";
exit if -e $lock_file;
#Set the PATH
$ENV{'PATH'} = "/bin:/usr/bin:/sbin";
system("touch $lock_file");
my $base_path = "/repo/centos";
my $version = "7.9.2009";
my @parts = qw ( centosplus os updates extras contrib epel );
#my @parts = qw ( epel );
#Invoke the rsync to update the repo
#For rpmforge, use this one rsync://ftp-stud.fht-esslingen.de/dag
foreach (@parts) {
next if $_ eq 'contrib';
if ( $_ eq 'epel' ) {
system( "rsync -avSHP --exclude 'debug' --exclude 'repodata' --exclude 'repoview' --delete --delete-excluded rsync://mirror.sjtu.edu.cn/fedora/epel/7/x86_64/ $base_path/$version/$_/x86_64/Packages/");
}else {
#system( "rsync -avSHP --delete rsync.mirrors.ustc.edu.cn::repo/centos/$version/$_/x86_64/Packages/ $base_path/$version/$_/x86_64/Packages/");
#update: need to remove the repo prefix
system( "rsync -avSHP --delete rsync.mirrors.ustc.edu.cn::centos/$version/$_/x86_64/Packages/ $base_path/$version/$_/x86_64/Packages/");
}
}
#Invoke createrepo
foreach (@parts) {
system("ssh core createrepo --workers 16 $base_path/$version/$_/x86_64");
}
unlink $lock_file;
|
在core上面讲mirror通过https的形式提供给其他人,具体的方法如下
1
2
3
4
5
6
7
| root@core: #-> cat /etc/httpd/conf.d/repo.conf
Alias /centos "/repo/centos"
<Directory /repo/centos>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Require all granted
</Directory>
|
最后修改机器的更新源为core
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
39
40
| root@core: #-> cat /etc/yum.repos.d/local.repo
[local-base]
name=local-$releasever - Base
baseurl=https://core.ic.X.com/centos/$releasever/os/$basearch/
gpgkey=https://core.ic.X.com/centos/$releasever/RPM-GPG-CentOS-7
gpgcheck=1
enabled=1
[local-updates]
name=local-$releasever - Updates
baseurl=https://core.ic.X.com/centos/$releasever/updates/$basearch/
gpgkey=https://core.ic.X.com/centos/$releasever/RPM-GPG-CentOS-7
gpgcheck=1
enabled=1
[local-extras]
name=local-$releasever - Extras
baseurl=https://core.ic.X.com/centos/$releasever/extras/$basearch/
gpgkey=https://core.ic.X.com/centos/$releasever/RPM-GPG-CentOS-7
gpgcheck=1
enabled=1
[local-centosplus]
name=local-$releasever - Plus
baseurl=https://core.ic.X.com/centos/$releasever/centosplus/$basearch/
gpgkey=https://core.ic.X.com/centos/$releasever/RPM-GPG-CentOS-7
gpgcheck=1
enabled=1
[local-contrib]
name=local-$releasever - Contrib
baseurl=https://core.ic.X.com/centos/$releasever/contrib/$basearch/
gpgcheck=0
enabled=1
[local-epel]
name=local-$releasever - Epel
baseurl=https://core.ic.X.com/centos/$releasever/epel/$basearch/
gpgcheck=0
enabled=1
|
安全设置
selinux
这个东西很好,但是也很麻烦,如果不是很会折腾,建议关闭:
编辑 /etc/sysconfig/selinux, 将里面的SELINUX更改成disabled,然后重启
ssh限制
需要在/etc/ssh/sshd_config里面做如下配置
- 普通用户关闭ssh登录权限
- 打开core上的git登录权限,这是为了使用ssh进行git的checkout
- 只允许基于ssh key的登录方式,这是为了防止MTIM攻击
防火墙配置
内网的机器可以把防火墙都关掉
portal上面的防火墙只开放必要的端口,INPUT/OUTPUT/FORWARD的policy都设置成DROP
portal作为登录机器是不允许跑EDA软件的,所以在core的防火墙上面要阻止来自portal的license请求
另外需要注意虚拟机的网络是不受iptables控制的,所以在portal上绝对绝对不要装虚拟机软件,不让网络无法管控
ETX 配置
限制最大拷贝数
profile -> general -> optional settings 里面添加如下配置(最大只允许拷贝512个字符)
1
| proxy.AllowCopyFromX=512
|
限制用户编辑profile
如果允许用户自己编辑profile,他就可以设置一个profile允许上传和下载,这无疑是有问题的
邮件发送
jenkins/gitlab等都有发送邮件的需求,但是core本身是无法连接外网的,解决方法就是要借助core
需要有一个专门的邮件账号用来发邮件(jarvis),这个账号只能开放smtp功能,不能开放 imap功能,这主要是为了防止有用户发完邮件又通过imap将发送邮件删除,从而销毁证据
具体步骤如下
- 在portal上面开一个邮件代理,只允许特定IP连接本地的465端口
- 在core上,只有特定用户才可以连接到core的465端口,包括以下用户
- ETX 服务: root
- jenkins服务: jenkins
- 上面两个步骤是确保用户无法使用自己的邮箱发送邮件,而只能通过jarvis账号发送
- jarvis账号会将所有内容存档,便于安全审计
邮件代理可以用nginx处理,关键配置如下
1
2
3
4
5
6
7
8
9
10
11
| root@portal0:~ #-> cat /etc/nginx/stream/mail_pro.conf
upstream mailsmtp_pro {
server smtp.qiye.aliyun.com:465;
}
server {
listen 465;
proxy_connect_timeout 5s;
proxy_timeout 5s;
proxy_pass mailsmtp_pro;
}
|
目录夹权限
下面这些文件夹需要设置合适的权限保证普通用户无法看到
- /proj/git: 里面存放了git的database
- /proj/xxx: 只有处于项目组xxx里面的人才能进入
- /data/backup: 需要保证普通用户无法访问备份文件夹