-前言
很多做android开发的小伙伴都知道,快速检索代码的利器opengrok,检索代码非常方便,本人之前多次搭建opengrok,只不过最近迫于代码安全性考虑,终于搞定opengrok+tomcat的ldap认证搭建,所以一并总结记录下。
opengrok的安装有两种方式,一种是docker安装,这个简单和快速,但不能做认证和授权,包括大型项目也不建议(其实实测AOSP代码也是没问题的,取决于你的服务器性能),可参考:https://github.com/oracle/opengrok/tree/master/docker#readmehttps://github.com/oracle/opengrok/tree/master/docker#readme
而另外一种安装方式就是本例即将介绍的,ubuntu+opengrok+tomcat集成搭建,本质上opengrok不支持账号认证,支持授权,因此本例是通过tomcat账号认证,opengrok进行账号的授权配置。
准备工作
1,opengrok安装包:Releases · oracle/opengrok · GitHub 我们下周最新的opengrok 1.7.18
2,本例中ubuntu版本 Ubuntu 20.04.2 LTS
3,根据官方描述,此版本的opengrok要求JDK 11以上,如果没有直接在官网下载deb包手动安装
因为oracle 的JDK9以上ubuntu已经不支持 类似安装了
sudo dpkg -i ~/tools/jdk-11.0.11_linux-x64_bin.deb
4,安装universal-ctags ,具体安装参照,替代ubuntu默认的Exuberant ctagsUniversal Ctags · GitHubUniversal Ctags has 13 repositories available. Follow their code on GitHub.https://github.com/universal-ctags
5,需要安装Git 2.6以上的工具
sudo apt-get install git
Tomcat安装
一般来说,ubuntu20.4 使用 sudo apt-get install tomcat,但是发现安装后是tomcat 9.0,但opengrok官网要求tomcat 10.0以上,因此只能手工原始安装tomcat了,参照:在Ubuntu 20.04系统上安装和配置Apache Tomcat 10的方法_Linux云服务器_云网牛站
一,下载tomcat 10.1.0-M5
从官网下载最新的apache-tomcat
Apache Tomcat® - Apache Tomcat 10 Software Downloads
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.0-M5/bin/apache-tomcat-10.1.0-M5.tar.gz
下载后解压缩apache-tomcat-10.1.0-MD5.tar.gz文件:
tar xvf apache-tomcat-10.1.0-MD5.tar.gz
将提取的文件移动到/usr:
sudo mv apache-tomcat-10.1.0-M5 /usr/share/apache-tomcat
创建apache tomcat用户:
sudo useradd -M -d /usr/share/apache-tomcat tomcat
sudo chown -R tomcat /usr/share/apache-tomcat
二,配置Apache Tomcat 10
允许从受信任的网络/IP访问Apache Tomcat UI。
1、编辑文件:
sudo vim /usr/share/apache-tomcat/webapps/manager/META-INF/context.xml
sudo vim /usr/share/apache-tomcat/webapps/host-manager/META-INF/context.xml
修改允许行以添加要从中访问UI界面的IP:
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192.168.1.20" />
或者,注释掉IP地址限制以允许来自任何地方的连接:
<!--<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />-->
2、安全访问管理员/仪表板
我们需要保护对tomcat UI管理区域的访问,编辑文件:
sudo vim /usr/share/apache-tomcat/conf/tomcat-users.xml
在</tomcat-users>之前添加以下内容:
<!-- manager section user role -->
<role rolename="manager-gui" />
<user username="manager" password="StronPassw0rd123" roles="manager-gui" />
<!-- admin section user role -->
<role rolename="admin-gui" />
<user username="admin" password="StronPassw0rd123" roles="manager-gui,admin-gui" />
3、配置系统服务
为Tomcat 10创建Systemd单元文件:
sudo vim /etc/systemd/system/tomcat.service
然后将以下内容粘贴到文件中:
[Unit]
Description=Tomcat
After=syslog.target network.target
Documentation=https://tomcat.apache.org/tomcat-9.0-doc/index.html
RequiresMountsFor=/var/log/tomcat10 /var/log/tomcat10
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="JAVA_OPTS=-Djava.awt.headless=true"
Environment="CATALINA_TMPDIR=/tmp"
Environment=JDK_JAVA_OPTIONS="--add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED"
Environment="JAVA_HOME=/usr/lib/jvm/default-java"
Environment="JAVA_HOME=/usr/lib/jvm/jdk-11.0.11/"
Environment="CATALINA_HOME=/usr/share/apache-tomcat"
#Environment=CATALINA_BASE=/usr/share/apache-tomcat
Environment='CATALINA_BASE=/var/lib/tomcat10'
Environment='CATALINA_PID=/var/lib/tomcat10/tomcat.pid'
ExecStart=/usr/share/apache-tomcat/bin/catalina.sh start
ExecStop=/usr/share/apache-tomcat/bin/catalina.sh stop
# Logging
SyslogIdentifier=tomcat10
# Security
User=tomcat
Group=tomcat
PrivateTmp=true
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE
CacheDirectory=tomcat10
CacheDirectoryMode=750
ProtectSystem=strict
#ReadWritePaths=/etc/tomcat10/Catalina/
ReadWritePaths=/var/lib/tomcat10/webapps/
ReadWritePaths=/var/log/tomcat10/
ReadWritePaths=/var/log/tomcat10/webapps/lib
ReadWritePaths=/home/jenkins/opengrok/
ReadWritePaths=/usr/share/apache-tomcat/conf/
ReadWritePaths=/home/jenkins/opengrok/index/suggester/
[Install]
WantedBy=multi-user.target
重新加载systemd守护程序:
sudo systemctl daemon-reload
运行以下命令以启动tomcat服务:
sudo systemctl restart tomcat
启用tomcat以在系统引导时启动:
sudo systemctl enable tomcat
如果启动成功,则应该在系统上看到Java进程正在使用的8080端口:
sudo ss -tunelp | grep 8080
[sudo] password for jenkins:
tcp LISTEN 0 100 *:8080 *:* users:(("java",pid=808616,fd=40)) uid:998 ino:45799734 sk:54 v6only:0 <->
尝试使用服务器IP地址或其主机名访问Web浏览器上的8080端口:
opengrok安装
一,安装准备
1,创建~/opengrok/ 保存安装安装包,配置已经索引文件和源码问题
mkdir /opengrok/{src,data,dist,etc,log}
下载安装包,然后解压到~/opengrok/dist/
Releases · oracle/opengrok · GitHubhttps://github.com/oracle/opengrok/releases
wget /https://github.com/oracle/opengrok/releases/download/1.7.18/opengrok-1.7.18.tar.gz
tar -C /opengrok/dist --strip-components=1 -xzf opengrok-X.Y.Z.tar.gz
2, 工程配置(可选)
默认日志配置从dist里面拷贝
cp ~/opengrok/dist/doc/logging.properties ~/opengrok/etc
日志的配置文件如下:
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
java.util.logging.FileHandler.pattern = ~/opengrok/log/opengrok%g.%u.log
java.util.logging.FileHandler.append = false
java.util.logging.FileHandler.limit = 0
java.util.logging.FileHandler.count = 30
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.formatter = org.opengrok.indexer.logger.formatter.SimpleFileLogFormatter
java.util.logging.ConsoleHandler.level = WARNING
java.util.logging.ConsoleHandler.formatter = org.opengrok.indexer.logger.formatter.SimpleFileLogFormatter
org.opengrok.level = FINE
索引同步的时候添加-Djava.util.logging.config.file 就可以使能日志保存,参照opengrok index
opengrok 项目部署
现在该将opengrok作为tomcat的一个web应用部署了,有两种方式:
1,手动拷贝到/var/lib/tomcat10/webapps/目录下,tomcat
会自动部署
sudo cp ~/opengrok/dist/lib/source.war /var/lib/tomcat10/webapps/
浏览网页http://localhost:8080/source,会提示configuration找不到,这个需要镜像索引才能生成,默认目录会在/var/opengrok/etc/configuration.xml
如需手动修改configuration.xml路径,可修改/var/lib/tomcat10/webapps/source/WEB-INF/web.xml文件中的CONFIGURATION字段,具体如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>OpenGrok</display-name>
<description>A wicked fast source browser</description>
<context-param>
<description>Full path to the configuration file where OpenGrok can read its configuration</description>
<param-name>CONFIGURATION</param-name>
<param-value>/opengrok/etc/configuration.xml</param-value>
</context-param>
...
2,脚本部署
实际的效果和手动拷贝一样,-c 可以指定CONFIGURATION
opengrok-deploy -c ~/opengrok/etc/configuration.xml \
~/opengrok/dist/lib/source.war /var/lib/tomcat10/webapps
opengrok项目索引
1,创建所以所需的目录index,和src
~/opengrok/index 和~/opengrok/index/suggester/ ,请确保opengrok 对以上目录有访问权限,否则索引不成功,或者出现搜索没有候选项
mkdir -p ~/opengrok/src/ ~/opengrok/index/suggester
chmod 777 ~/opengrok/index/suggester
下载两个测试用的实例项目
cd ~/opengrok/src
# use one of the training modules at GitHub as an example small app.
git clone https://github.com/githubtraining/hellogitworld.git
# use OpenGrok as an example large app
git clone https://github.com/OpenGrok/OpenGrok
2,执行索引命令
opengrok_base="/home/jenkins/opengrok/"
java \
-Djava.util.logging.config.file=${opengrok_base}/etc/logging.properties \
-jar ${opengrok_base}/dist/lib/opengrok.jar \
-c ${ctags_root} \
-R ${opengrok_base}/etc/readonly-configuration.xml \
-s ${opengrok_base}/src \
-d ${opengrok_base}/index -H -P -S -G --progress -v \
-U "http://localhost:8080/source" \
-W ${opengrok_base}/etc/configuration.xml
索引完成后,浏览器 访问 http://localhost:8080/source
3,定时索引
使用crontab命令实现定时同步
* 0 * * * /home/jenkins/opengrok/opengrok_index.sh > /home/jenkins/opengrok/log/opengrok_index.lo
LDAP认证配置
我的认证策略比较简单,特定组的账号只能登陆访问,如刚开始讲的,Tomcat实现账号认证,opengrok实现授权。
1,Tomcat 配置server.xml,ldap认证需要使用JNDIRealm
打开/var/lib/tomcat10/conf/server.xml,删除UserDatabase
<!--
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
-->
删除<Engine name="Catalina" defaultHost="localhost">里面的UserDatabaseRealm,并添加<Realm className="org.apache.catalina.realm.JNDIReal ,我这里添加到Engine里,其实也可以添加到Host和Context里,只是权限的影响范围不一样。
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm.-
<!-- comment for ldap
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99"
connectionURL="ldap://ldap.xxx.com:389"
userBase="OU=XX开发部,cn=Directory Manager"
userSearch="(sAMAccountName={0})"
userSubtree="true"
connectionName="username"
connectionPassword="Tpass"
/>-
>-<Valve className="org.apache.catalina.valves.AccessLogValve"
pattern="%h %l %u %t "%r" %s %b %{Authorization}i"
prefix="catalina_access_log" suffix=".txt"/>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
参数名 | Realm 属性 | 参数值 | 注释 |
LDAP 链接 URL | connectionURL | ldap://localhost:389 | LDAP服务器和 Tomcat 在同一台机器上。389 为 LDAP服务器的端口 |
LDAP 绑定用户 | connectionName | cn=Directory Manager | Sun Directory Server 的目录管理员 |
绑定用户密码 | connectionPassword | Secret | |
用户搜索模板 | userPattern | uid={0},ou=People,dc=example,dc=com | |
用户密码 | userPassword | userPassword | 用户登录时的密码, 为 LDAP 中条目的 userPassword 属性 |
角色搜索路径 | roleBase | ou=Groups,dc= example,dc= com |
|
角色属性 | roleSearch | (uniqueMember={0}) | 对应角色中的成员 |
搜索角色子目录 | roleSubtree | False | 可以不设定 |
Apache Tomcat 10 (10.0.11) - Realm Configuration How-To
Ldapwiki: Tomcat And LDAP
可参照在Tomcat 5.5 中使用 LDAP 进行用户认证_davidgjm的专栏-CSDN博客
2,opengrok权限授权配置
insert.xml 需要将下面insert.xml嵌入到opengrok的webapp/WEB-INF/web.xml ,可以手动添加,也可以用命令插入,其中login-config用来设定网页进入的登陆方式,如果生效,就提示让用户输入账号和密码才能访问
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<!-- insert some elements here -->
<security-constraint>
<web-resource-collection>
<web-resource-name>API endpoints are checked separately by the web app</web-resource-name>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>In general everything needs to be authenticated</web-resource-name>
<url-pattern>/*</url-pattern> <!-- protect the whole application -->
<url-pattern>/api/v1/search</url-pattern> <!-- protect search endpoint whitelisted above -->
<url-pattern>/api/v1/suggest/*</url-pattern> <!-- protect suggest endpoint whitelisted above -->
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-role>
<role-name>*</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
</web-app>
用一下命令插入:
opengrok-deploy --insert insert.xml ~/opengrok/dist/lib/source.war \
/var/lib/tomcat10/source/webapps/source.war
然后浏览网页localhost:8080/source/出现以下提示
如果不提示,需要排查web.xml的配置,我们发现用脚本插入会出现一些乱码,建议用手工插入
3 使用LDAP插件添加配置
添加readonly configuration file
~/opengrok/etc/readonly-configuration.xml
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_172" class="java.beans.XMLDecoder">
<object class="org.opengrok.indexer.configuration.Configuration" id="Configuration0">
<void property="pluginStack">
<!-- The setup will be inherited to all sub-stacks -->
<void property="setup">
<void method="put">
<string>configuration</string>
<string>/opengrok/auth/config/ldap-plugin-config-corp.xml</string>
</void>
</void>
<!-- Place for authorization sub-stacks and/or authorization plugins -->
</void>
<!-- Authorization config end -->
</object>
</java>
ldap-plugin-config-corp.xml
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_65" class="java.beans.XMLDecoder">
<object class="opengrok.auth.plugin.configuration.Configuration">
<void property="interval">
<int>900000</int>
</void>
<void property="searchBase">
<string>dc=foo,dc=com</string>
</void>
<void property="webHooks">
<object class="opengrok.auth.plugin.util.WebHooks">
<void property="fail">
<object class="opengrok.auth.plugin.util.WebHook">
<void property="URI">
<string>http://localhost:8080/source/api/v1/messages</string>
</void>
<void property="content">
<string>{ "tags": [ "main" ], "cssClass": "class", "text": "corporate LDAP failed", "duration": "PT10M" }</string>
</void>
</object>
</void>
</object>
</void>
<void property="countLimit">
<int>10</int>
</void>
<void property="connectTimeout">
<int>3000</int>
</void>
<void property="searchTimeout">
<int>3000</int>
</void>
<void property="readTimeout">
<int>1000</int>
</void>
<void property="servers">
<void method="add">
<object class="opengrok.auth.plugin.ldap.LdapServer">
<void property="name">
<string>ldap://ldap.foo.com</string>
</void>
<void property="connectTimeout">
<int>3000</int>
</void>
</object>
</void>
</void>
</object>
</java>
以上配置都是通过索引的时候配置的,因此可参照执行索引命令 的索引命令,添加添加。
重启tomcat,浏览localhost:8080/source,即可进行ldap账号认证。
问题定位:
tomcat的日志在/var/lib/tomcat10/log/
opengrok 日志 ~/opengrok/log