操作系统版本:Centos 7 2003
开发人员反馈通过socat做正向代理,连接socat代理返回permission denied,根据日志查看发现执行connect函数时返回EACCES,即permission denied。注:程序是root用户执行的
man connect查看返回错误可能原因:
EACCES For Unix domain sockets, which are identified by pathname: Write permission is denied on the socket file, or search permission is denied for one of the directories in the path prefix. (See also path_resolution(7).)
EACCES, EPERM
The user tried to connect to a broadcast address without having the socket broadcast flag enabled or the connection request failed because of a local firewall rule.
以为是操作系统防火墙或selinux问题,通过排查发现防火墙是关闭的,selinux也未启用
换nc测试,发现nc与socat返回结果相同,也是没有权限
跟踪调用栈
通过perf record -p PID -ag,再根据perf script得到socat程序执行connect时内核中的调用栈:

根据内核源码发现,从调用栈中的filter_get_sock_type函数开始就不属于内核源码,因此想到一种可能,就是安装了其他的内核模块。
进一步查看内核模块:执行lsmod,发现系统中很多内核模块,根据内核模块名通过find / -name '内核模块名*'查找内核模块路径,找到后执行nm '内核模块名绝对路径' | grep filter_get_sock_type,在其中某个模块中果然找到此函数,剩下的函数同样方法查找,也都在此模块中,因此问题发现,原因是客户安装了自己或第三方实现的防火墙,此防火墙阻止了相关程序执行connect函数
本文详细记录了在Centos7系统中使用socat进行正向代理时遇到的permission denied问题,通过深入分析内核调用栈,最终定位到客户自定义或第三方防火墙模块导致的问题,并提供了排查思路。
266

被折叠的 条评论
为什么被折叠?



