我正在开发一个广泛使用套接字的 C 应用程序。
我的疑问是:我创建的每个套接字是否都有自己的缓冲区来发送和/或从其他套接字接收消息?
换句话说,套接字是否会受到错误消息交换的影响?
我所说的错误是指发送到一个套接字的消息可以“泄漏”到另一个套接字,而无需编写(并且可能是错误的)程序代码将消息从“预期”接收器显式传输到另一个套接字。
如果我运行 rsh,它可以工作,但会在开头打印一些奇怪的“连接被拒绝”消息:
$ rsh localhost pwd
connect to address 127.0.0.1 port 544: Connection refused
Trying krb4 rsh...
connect to address 127.0.0.1 port 544: Connection refused
trying normal rsh (/usr/bin/rsh)
/home/service
Run Code Online (Sandbox Code Playgroud)
但是如果我在 strace 下运行 rsh,它根本不会连接到服务器:
$ strace -c rsh localhost ulimit -n
connect to address 127.0.0.1 port 544: Connection refused
Trying krb4 rsh...
connect to address 127.0.0.1 port 544: Connection refused
trying normal rsh (/usr/bin/rsh)
rcmd: socket: Permission denied
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- …Run Code Online (Sandbox Code Playgroud) 我正在使用启用的grsecurity内核CONFIG_GRKERNSEC_SOCKET_SERVER:
[*] Socket restrictions
[ ] Deny any sockets to group (NEW)
[ ] Deny client sockets to group (NEW)
[*] Deny server sockets to group
Run Code Online (Sandbox Code Playgroud)
这可以防止用户创建“服务器”套接字(即启动 Apache),但允许打开客户端套接字(即 Firefox)。
实际上,所有网络客户端都可以正常工作(Firefox、telnet、ssh、nc、w3m 等)。只有 Chrome 浏览器 (Chromium) 不起作用。
从命令行启动 chrome 时,出现以下错误:
ERROR:address_tracker_linux.cc(138)] Could not bind NETLINK socket: Permission denied
libudev: udev_monitor_enable_receiving: bind failed: Permission denied
FATAL:udev_linux.cc(31)] Check failed: 0 == ret (0 vs. -1)
Aborted
Run Code Online (Sandbox Code Playgroud)
在日志中,我看到:
grsec: denied bind() by /usr/lib/chromium/chromium[NetworkChangeNo:3920]
grsec: denied bind() by /usr/lib/chromium/chromium[WorkerPool/3922:3922]
grsec: denied bind() …Run Code Online (Sandbox Code Playgroud) 我正在使用的端口无法在进程重新启动时绑定。我想知道何时考虑使用端口?
是否仅在 LISTEN 模式下?如果连接在 TIME_WAIT 状态(或 TCP有限状态机中的任何其他状态)下打开到端口,也可以吗?
tcp 0 0 127.0.0.1:7199 0.0.0.0:* LISTEN 30099/java
tcp 0 0 192.168.1.2:9160 0.0.0.0:* LISTEN 30099/java
tcp 0 0 192.168.1.2:58263 192.168.1.2:9042 TIME_WAIT -
tcp 0 0 192.168.1.2:58262 192.168.1.2:9042 TIME_WAIT -
tcp 0 0 ::ffff:192.168.1.2:9042 :::* LISTEN 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57191 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57190 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:10.176.70.226:37105 ESTABLISHED 30099/java
tcp 0 0 ::ffff:127.0.0.1:42562 ::ffff:127.0.0.1:7199 TIME_WAIT -
tcp 0 0 ::ffff:192.168.1.2:57190 ::ffff:192.168.1.2:9042 ESTABLISHED 30138/java
tcp …Run Code Online (Sandbox Code Playgroud) 我知道在 RedHat 中,我可以在 IP 表中阻止传入连接到本地端口。我还可以阻止来自特定 IP 的连接。
但是是否可以阻止来自特定 IP 地址的连接,并且连接尝试是通过在外部 IP 上的特定端口上运行的服务进行的?
所以如果我有类似的东西,
iptables -A INPUT -s 202.54.20.22 -j DROP
iptables -A OUTPUT -d 202.54.20.22 -j DROP
Run Code Online (Sandbox Code Playgroud)
我是否可以为该特定 IP 地址指定更多特异性并选择要阻止的特定端口?假设该服务在 202.54.20.22 的端口 5000 上运行,我可以具体说一下吗?请注意,此服务可能不会尝试连接到服务器上的端口 5000,因此仅阻止服务器上的该端口并不是我所追求的。
所以在我拿起斧头摧毁我的桌面之前,我会试着在这里问:-)
我有一个名为commander.service 的套接字激活服务。由于简单,我只想将裸字符串或字符推送到此服务。
所以我有一个commander.socket文件:
[Socket]
ListenFIFO=/run/commander.sk
[Install]
WantedBy=sockets.target
Run Code Online (Sandbox Code Playgroud)
然后我有一个commander.service文件:
[Unit]
Description=A service reading commands from the given socket
[Service]
ExecStart=/usr/bin/perl /root/commander.pl
StandardInput=socket
User=root
Group=root
Restart=no
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
现在我希望我在那里运行的脚本通过标准输入接收这些字符串或字符。
脚本的代码是:
#!/usr/bin/env perl
my $in = *STDIN;
my $out = *STDOUT;
$out->print("My printing reaches the outside world\n");
while($_ = <$in>) {
$out->print("Received: ");
$out->print($_);
$out->print("\n");
if($_ == "1") {
$out->print("I should run the command associated with 1 ;-) \n");
} elsif($_ == "2") {
$out->print("I should run the command associated with 2 …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 FreeBSD 上设置 nginx 和 cgit,但 nginx 无法访问/var/run/fcgiwrap/fcgiwrap.sock.
在我的/etc/rc.confI 中fcgiwrap_user="www",我已经设置了,www也是 nginx 运行的用户。
当我由表演fcgiwrap.sock拥有时,一切都按我想要的方式工作。wwwchown www /var/run/fcgiwrap/fcgiwrap.sock
然而,这当然不是正确的方法,它只会持续到重新启动。
我假设设置fcgiwrap_user="www"也会决定这一点。
我错过了什么吗?
更新:
我注意到当我使用service fcgiwrap startor 时restart,消息Starting fcgiwrap后面跟着chmod: /var/run/fcgiwrap/fcgiwrap.sock: No such file or directory. 然而/var/run/fcgiwrap/fcgiwrap.sock之后确实存在。
man mount
SO_RCVBUF
设置或获取最大套接字接收缓冲区(以字节为单位)。内核在使用setsockopt(2) 设置时将该值加倍(为簿记开销留出空间),并且这个加倍的值由getsockopt(2) 返回。默认值由 /proc/sys/net/core/rmem_default 文件设置,允许的最大值由 /proc/sys/net/core/rmem_max 文件设置。此选项的最小(加倍)值为 256。
但我认为这样的缓冲区不能容纳任何数据包
Linux 可以使用哪些值作为默认的 unix 套接字缓冲区大小?
...
每个数据包的开销是 struct sk_buff 和 struct skb_shared_info 的组合,因此它取决于这些结构的确切大小(为了对齐而稍微向上取整)。例如,在上面的 64 位内核中,每个数据包的开销是 576 字节。
以上正确吗?内核强制执行最小套接字缓冲区大小为 256 有什么好的理由吗?
https://zaiste.net/ssh_port_forwarding/#remote-port-forwarding
远程端口转发是使用 -R 参数创建的。
Run Code Online (Sandbox Code Playgroud)ssh -R source_port:forward_to_host:destination_port via_host此命令连接到 via_host。via_host 运行一个 SSH 服务器。然后它将所有连接尝试转发到远程 via_host 机器上的 source_port 到本地机器(启动 ssh 命令的机器)上的 destination_port 端口。forward_to_host 机器必须可以从本地机器访问。转发也可以通过 Unix 套接字完成。
“转发也可以通过Unix套接字完成”是什么意思?这是怎么做的?
ssh 远程端口转发不是通过 Unix 套接字完成的,而是通过 Internet 套接字完成的?
谢谢。
从APUE:
17.3 独特的连接
一台服务器可以安排独特的UNIX域连接使用标准的客户
bind,listen和accept功能。客户端connect用来联系服务器;服务器接受连接请求后,客户端和服务器之间存在唯一连接。这种操作方式与我们用Internet 域套接字说明的相同在图 16.16 和 16.17。
如果我是对的, 两个 Internet 域 TCP 套接字之间最多只能有一个连接。
两个 Unix 域套接字之间可以有多少个连接?
如果最多也有一个,那为什么书中专门用一节来使两个 unix 域套接字之间的连接唯一?
谢谢。