首页 / 资讯中心 / 文章详情

自建Portal认证服务器:OpenPortalServer部署与排坑指南

自建Portal认证服务器:OpenPortalServer部署与排坑指南 ★ FEATURED ARTICLE
简介这份资源是基于Java开发的开源PORTAL协议服务端程序适合网络管理员、运维工程师以及需要部署认证上网环境的开发者使用。程序兼容华为、H3C、锐捷、爱快等主流网络设备支持标准Portal协议、V1/V2及CMCC协议并涵盖PAP、CHAP认证方式可提供一键认证、外部Radius认证、微信认证、APP认证、短信认证和动态密码认证等多种接入方案。包内共有1477个文件包含编译后的class、可执行jar、Java源码结构、JSP页面、XML配置及SQL脚本等涵盖服务端运行、模板展示与数据初始化等用途另有sh/bat脚本、常用工具与PDF文档便于部署参考。压缩包约51.99MB已有1366人学习下载。借助SpringMVC、Mybatis、Shiro等主流框架读者可获得一套完整可用的认证平台源码适合二次开发或直接搭建生产级认证环境。1. 这是干什么的不开商业平台也能把Web认证跑起来前几天一个做WiFi运营的朋友突然找我说他们的商业AC只认PORTAL协议但云认证平台因为合规要求不能接到内网。这时候一台能自己部署的Portal服务端程序就成了关键。OpenPortalServer就是干这个的它装在Linux上对接AC和RADIUS把未认证用户重定向到认证页面完成一次完整的Web认证。它不依赖任何厂商云平台V3.3.5.6虽然是2016年的稳定版但PORTAL协议这么多年没有大改至今还能用在IPv4的商用WiFi和园区网里。这篇笔记我照着这个版本实际拆过一遍从协议流程到配置文件再到部署时踩过的坑都写给你看。需要内网自建认证入口的同学这份资源值得你下载下来跑一遍。2. PORTAL协议流程与OpenPortalServer选型先搞懂谁在牵头Portal认证不是服务端单方面干活它跟AC、用户浏览器、RADIUS形成一个四方协作的链路。很多人在部署时翻车就是因为只配置了服务端不知道AC侧还有一堆隐藏条件。这一章先把协议流程和选型逻辑说清楚再给你一个抓包验证方法。2.1 协议流程HTTP重定向、心跳保活与认证状态转移未认证用户连接WiFi后访问任意HTTP站点AC通过ACL规则拦截返回302重定向到Portal服务端的认证页面URLURL里带着用户IP、MAC、AC的标识这个动作叫“强制重定向”。用户填完账号密码提交服务端先把凭据通过RADIUS Access-Request发给认证服务器认证通过返回Access-Accept后服务端向AC发送认证成功确认报文AC收到后修改用户策略打开放行权限。同时服务端和AC之间还有周期性的Echo心跳报文用来检测设备是否在线。这个流程里最容易出错的是“认证成功后谁负责放行”。很多新手以为RADIUS返回成功就完事了实际上服务端和AC之间的status报文才是关键。如果AC没收到确认报文用户即使密码正确也照样上不了网。所以配置时AC上的共享密钥、服务端IP、报文端口三者必须完全一致。我见过最典型的案例是AC侧把Portal服务器端口写成了8080而协议报文走的是UDP 2000结果用户页面能打开但认证状态一直卡在“在线检测”。认证状态转移分三步初始时用户在AC上的状态是“未认证”AC只允许DNS和Portal页面的流量通过提交凭证并通过RADIUS校验后服务端通知AC把状态改为“已认证”客户端断线重连或超时后状态回落到“未认证”。理解这个状态机你就知道为什么AC上会有“强制下线”“会话老化”这些参数了。调试时服务端日志里会打印状态变化看到“auth success”不代表AC已经放行还要再看后续的ACK报文。2.2 选型理由为什么OpenPortalServer这个2016年的稳定版还能打开源社区里Portal服务端不少但很多项目追求新特性把协议版本改得不兼容。OpenPortalServer V3.3.5.6还能用是因为它严格实现了标准PORTAL协议兼容主流商业AC的重定向机制。它的源码包不大依赖少编译简单适合放在内网服务器上长期跑。我选它还有两个理由一是支持CHAP和PAP两种认证加密方式二是有详细日志出错时能直接看出AC交互报文的内容。当然2016年的版本也有局限。比如它不支持IPv6地址的Portal页面跳转不支持Cookie持有登录态也没有Web管理界面。如果你的场景是纯IPv6的校园网那这个版本不适合你如果是IPv4为主的商业WiFi或园区网络它足够稳定。做选型时一定要先确认自己AC厂商的报文格式是哪一版协议再决定用哪个版本。我建议你先看AC的Portal参数里有没有“协议版本选择”如果有选“标准协议”或“V1”版本OpenPortalServer对V1兼容性最好。还有人会问为什么不直接用开源RADIUS加上自写重定向答案是AC的重定向逻辑是私有的你自写服务器很难调通报文细节。用现成的Portal服务端等于把AC报文解析、心跳握手、异常重传这些脏活累活都接住了。我做技术选型的原则是“能用现成组件解决的不自己造轮子”这也是我几次更换方案后最终固定在这个版本上的原因。2.3 抓包验证用tcpdump快速确认协议交互是否正常部署完以后先别急着让真实用户测试我一般会在服务端上抓包看协议报文。以下命令抓取来自AC的报文Portal协议默认走UDP 2000端口同时把HTTP流量也带上tcpdump -i eth0 -s 0 -w /tmp/portal.pcap tcp port 2000 or udp port 2000 or tcp port 80这条命令的意思是监听eth0网卡不截断报文-s 0把抓到的内容写入/tmp/portal.pcap文件。过滤条件有三类TCP/UDP 2000端口对应AC和服务端的协议通信TCP 80端口对应认证页面的HTTP访问。抓完让一个测试用户访问认证页面10秒后按CtrlC停止抓包。抓完用wireshark打开pcap文件你需要看三个关键点第一有没有来自AC的REQ_CHALLENGE或REQ_AUTH报文第二服务端有没有回ACK第三用户POST到认证页面的HTTP请求有没有被正确解析。如果你发现只有用户HTTP请求没有AC报文那问题大概率不在服务端而是AC侧Portal服务器地址没指对。抓包是定位“谁没干活”的最快手段比翻日志猜参数强十倍。3. 部署与配置从源码包到一套能用的认证服务下载下来的源码包解压后是一个标准的C项目目录有src、conf、web等目录。这章带你把编译、配置、AC对接、页面定制走完每一步都有可复现的命令。3.1 编译安装与目录结构我的环境是CentOS 7用了gcc 4.8.5。编译前先确认安装了make和gcc然后进入源码根目录执行tar zxvf OpenPortalServer-V3.3.5.6-stable.tar.gz cd OpenPortalServer make make install第一行解压源码包包名里的“stable”代表这是稳定版分支。第二行进目录第三行make会读取Makefile开始编译第四行make install把生成的可执行程序安装到系统目录。如果make报错缺头文件用yum install gcc-c补齐开发环境。编译完成后默认安装到/usr/local/portal目录。你可以用find命令看看结构find /usr/local/portal -maxdepth 2 -type f | sort一般会有三个关键目录conf存放portal.conf和radius.confhtml存放认证页面bin存放portal_server可执行程序。我建议不要改安装目录因为源码里绝对路径写死的情况不少改目录会导致启动时找不到配置。如果你非要装到别处记得把所有引用路径一并改掉不然会出现“明明文件在程序却说加载失败”的玄学错误。3.2 配置文件核心参数portal.conf里每项都是命安装后第一步不是启动而是改配置。打开conf/portal.conf我贴一个我常用的最小配置[server] listen_ip 0.0.0.0 listen_port 8080 portal_port 2000 secret_key mytestkey123 auth_timeout 60 [radius] server 192.168.1.10:1812 secret radsecret timeout 3 retries 2 [network] nas_ip 192.168.1.20 portal_ip 192.168.1.21listen_ip是服务端监听地址通常用0.0.0.0表示监听所有网卡listen_port是认证页面的HTTP服务端口浏览器访问这个端口打开页面portal_port是跟AC通信的UDP端口必须和AC侧一致secret_key是AC接入的共享密钥AC上填的必须完全一样auth_timeout是认证超时时间单位秒用户在这个时间内没完成认证就重来。radius段是RADIUS服务器的地址IP和端口、共享密钥以及超时和重试次数。network段的nas_ip是你的AC设备IPportal_ip是Portal服务端本机IP。这两个IP主要用在AC侧的白名单和报文来源校验。有一点要特别注意secret_key不能带特殊字符有些AC固件处理特殊字符时会出错导致认证报文校验失败。我建议只用字母和数字长度不超过16位。3.3 对接AC共享密钥、IP白名单与端口对齐配置完服务端还要在AC上做三件套。第一步把AC的Portal服务器参数指向portal_ip和portal_port拿上面配置来说就是192.168.1.21和2000。第二步填写共享密钥必须和portal.conf里的secret_key完全一致。第三步在AC上把Portal服务器IP加入信任列表有些AC默认只接受和自己在同一网段的Portal服务器跨网段必须显式放行。这一步经常有人漏掉“AC的HTTP重定向白名单”。AC默认只对公网域名做重定向如果用户访问的是内网IPAC可能直接放行不弹认证。所以要在AC的认证策略里把认证页面域名或服务端IP加入“不重定向列表”否则会出现“用户访问内网资源直接进访问外网却跳不回来”的怪状。具体配置路径因AC品牌而异一般在“Portal认证”或“Web认证”策略里找端口和密钥。我用一个表格列出三端参数对齐点参数服务端portal.confAC侧配置Portal服务器IP192.168.1.21填入的Portal服务器地址通信端口portal_port2000选择PORTAL协议端口共享密钥secret_keymytestkey123Portal共享密钥RADIUS服务器radius.server192.168.1.10认证服务器地址这张表是我每次联调前必查的清单。通常问题就出在“AC侧配置”这一列有人把RADIUS服务器地址和Portal服务器地址填反了导致认证报文发到RADIUSRADIUS看不懂UDP 2000的包直接丢弃。3.4 定制认证页面一套能用的HTML与POST对接默认的页面很简陋通常我们会改一套带logo的页面。关键点是页面里的表单字段名必须符合服务端代码的解析逻辑。我拆过这个版本的源码发现它接收两个主要字段username和password。下面的页面可以直接用!DOCTYPE html html headmeta charsetutf-8titleWiFi认证/title/head body form methodpost action/portal/pc/login input typetext nameusername placeholder请输入账号 input typepassword namepassword placeholder请输入密码 input typehidden nameuserip value{{userip}} input typehidden nameusermac value{{usermac}} button typesubmit登录/button /form /body /html注意action地址是/portal/pc/login不是根目录这是服务端内部处理登录请求的URL。{{userip}}和{{usermac}}是服务端渲染模板变量实际会替换成AC重定向URL里带的参数。如果你用纯静态HTML这两个变量不会被替换提交后服务端无法获取用户来源导致认证失败。所以不要直接双击HTML测试要把它放在服务端的web目录里由服务端动态输出。逻辑说明POST表单需要回传AC重定向URL中携带的userip和usermac服务端用这两个字段建立用户会话。如果缺少隐藏字段服务端会返回“参数缺失”的错误。页面里的字符集声明必须和文件实际编码一致否则中文会乱码。我建议保存时用UTF-8 without BOM这是跨手机和PC兼容性最好的编码。4. 常见问题排查四个让我抓狂的Portal认证坑部署过程中我踩过不少坑这里挑四个最典型的每条都是现象、原因、解决三步写帮你省掉几天的排查时间。4.1 坑一用户打开百度浏览器一直转圈就是不出认证页面现象用户连接WiFi后访问http://www.example.com浏览器状态栏显示连接中但始终不跳转到认证页面。原因AC没有把HTTP请求重定向到Portal服务器。最常见的原因是AC上的Portal服务器端口填成了8080而协议报文端口实际是2000AC把重定向消息发到了错误端口。或者AC的“重定向ACL”里没有放行HTTP 80端口的流量导致重定向触发不了。解决先在AC上ping Portal服务器IP确认网络通。再检查AC的Portal server配置端口是否等于服务端portal_port。最后确认AC认证策略里的强制重定向开关是打开的。我那次就是端口不一致AC发的是2000服务端portal_port也写了2000但在AC上“HTTP重定向端口”默认是80没改成对应监听端口结果报文到了却不知道往哪转发。改完AC参数后重启一下AC的Portal进程才生效。4.2 坑二页面出来了账号密码也对但认证成功提示后仍然不能上网现象用户输入正确的账号密码页面提示“认证成功”但断连重连后依然无法访问互联网。原因服务端向AC发送了认证成功报文但AC没有收到或者校验失败。这背后往往是共享密钥不一致或者报文中的用户MAC地址格式不对。有的AC希望MAC是00:11:22:33:44:55有的AC希望是0011.2233.4455OpenPortalServer默认格式可能跟AC期望的不匹配。解决查看AC上的Portal用户日志确认有没有“Portal认证成功”的记录。如果没有抓包对比服务端发出的报文和AC期望格式。把密钥改成两边完全一样的字母数字组合不要带短横线。如果MAC格式不对需要在服务端源码里找MAC格式化函数改成AC要求的点分格式重新编译。这个坑很隐蔽因为页面和RADIUS表现都正常只有AC内部日志会提示“报文格式错误”。4.3 坑三RADIUS经常超时用户等很久才提示密码错误现象认证提交后浏览器要转10秒以上才返回“用户名或密码错误”而且错误提示不稳定有时直接说服务端不可用。原因服务端到RADIUS服务器的网络不稳定或者RADIUS服务器的timeout和retries设置过大。我见到的另一个原因是服务端监听地址写成了0.0.0.0收到RADIUS响应后不知道该回给哪个网卡导致响应丢包。还有可能是防火墙把UDP 1812端口丢弃了。解决先单独用radclient测试RADIUS认证确认RADIUS本身没问题。然后调小portal.conf里radius段的timeout为2、retries为1让失败快速暴露。把listen_ip改成实际的内网网卡IP不要用0.0.0.0。检查防火墙iptables -L -n | grep 1812这条命令会列出防火墙规则里有没有允许1812端口的规则。没有的话添加放行规则iptables -I INPUT -p udp --dport 1812 -j ACCEPT添加后要保存规则不然重启就丢了。这里还有个容易漏的点有些系统用ufw或者firewalld不是iptables要用对应的命令放行。4.4 坑四认证页面中文乱码提交后提示URL参数错误现象认证页在部分手机上显示乱码提交时报“参数错误”PC上又正常。原因页面文件用了GBK编码但服务端在HTTP响应头里没有指定charset浏览器默认用UTF-8解析导致中文乱码。另一个原因是AC重定向URL里的参数带了非ASCII字符服务端没做URL解码导致usermac参数被截断。解决在HTML的 里加上meta charsetutf-8同时在服务端源码里把HTTP响应头强制设置为Content-Type: text/html; charsetutf-8。保存页面文件时务必用UTF-8 without BOM格式不要用Windows记事本的默认ANSI。URL参数问题可以在AC侧把重定向URL里的参数都改成ASCII字符用户IP和MAC本身是十六进制和点分不会有中文但如果有自定义参数尽量别用中文。我建议在手机和PC上各测一次尤其注意微信内置浏览器它对编码的兼容性最差最容易暴露问题。5. 进阶用法多AC接入与配置一致性自检当你管理多个AC时每台AC的Portal服务器参数都要对齐手工配置容易漏。我习惯写一个配置自检脚本从服务端配置文件里提取关键参数再和AC导出的配置做文本比对。这个技巧能帮你快速发现哪台AC的密钥过期。5.1 多AC接入时的密钥规划多个AC接入同一个Portal服务端共享密钥可以统一为一个但为了方便排障我建议每个AC用不同的密钥。这个版本虽然只支持一个全局secret_key但你可以通过防火墙DNAT的方式把不同AC的报文源IP映射到不同端口再用iptables做转发实现密钥分区。不过这属于比较重的玩法一般场景一个密钥就够了。实际做的时候我在密钥里加上AC编号比如portal-ac01-key日志里直接能看出是哪个AC发的包。5.2 用脚本做配置一致性自检下面这个脚本读取portal.conf中的secret和AC配置导出文件报告不一致项#!/bin/bash # 从portal.conf提取密钥和AC导出的配置比对 PKEY$(grep ^secret_key /usr/local/portal/conf/portal.conf | awk -F {print $2}) for ac in ac1.conf ac2.conf; do AKEY$(grep PortalSecret $ac | awk {print $NF}) if [ $PKEY $AKEY ]; then echo $ac: PASS else echo $ac: FAIL expected$PKEY got$AKEY fi done脚本第2行提取服务端配置中的secret_key第3行循环遍历当前目录下的AC导出配置文件第4行从AC配置文件里抓取PortalSecret字段的最后一个值然后比对。如果一致显示PASS否则显示FAIL并列明预期值与实际值。AC导出文件的格式因厂商而异你需要根据自己的环境调整第4行的grep字段。我一般会把AC的配置文件集中备份到服务器上然后把这个脚本放进定时任务每周跑一次。自从用了这个脚本我再也没有遇到过“改了一台AC密钥忘了另一台”导致用户投诉断网的情况了。从那以后我每次调整认证参数都强制先跑一遍脚本确认所有AC配置一致再进入联调。这个习惯帮我省掉了大量重复登录AC的操作也避免了深夜里被叫起来处理“某个角落的AC认证失败”的问题。希望这次的拆解和踩坑记录能帮你在自建Portal认证的路上少走弯路。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站