- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在运行一个应用程序,它构建 ICMP ECHO 请求并将其发送到几个不同的 IP 地址。该应用程序是用 Crystal 编写的。尝试从 crystal docker 容器中打开套接字时,Crystal 引发异常:权限被拒绝。
在容器中,运行 ping 8.8.8.8
没有问题。
在 macOS 上运行应用程序,我没有问题。
阅读https://docs.docker.com/engine/security/apparmor/和 https://docs.docker.com/engine/security/seccomp/ apparmor 和 seccomp 上的页面 我确信我找到了解决方案,但问题仍然没有解决,即使以 docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission 运行时也是如此
更新/编辑:深入了解capabilities(7)
后,我将以下行添加到我的dockerfile:RUN setcap cap_net_raw+ep bin/ping
试图让套接字打开但没有改变。
谢谢!
相关的 Crystal socket 代码,完整的工作代码示例如下:
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
docker 文件:
FROM crystallang/crystal:0.23.1
WORKDIR /opt
COPY src/ping.cr src/
RUN mkdir bin
RUN crystal -v
RUN crystal build -o bin/ping src/ping.cr
ENTRYPOINT ["/bin/sh","-c"]
CMD ["/opt/bin/ping"]
运行代码,首先是原生的,然后是通过 docker:
#!/bin/bash
crystal run src/ping.cr
docker build -t socket_permission .
docker run --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined socket_permission
最后,一个无法在 docker 中打开套接字的 50 行 crystal 脚本:
require "socket"
TYPE = 8_u16
IP_HEADER_SIZE_8 = 20
PACKET_LENGTH_8 = 16
PACKET_LENGTH_16 = 8
MESSAGE = " ICMP"
def ping
sequence = 0_u16
sender_id = 0_u16
host = "8.8.8.8"
# initialize packet with MESSAGE
packet = Array(UInt16).new PACKET_LENGTH_16 do |i|
MESSAGE[ i % MESSAGE.size ].ord.to_u16
end
# build out ICMP header
packet[0] = (TYPE.to_u16 << 8)
packet[1] = 0_u16
packet[2] = sender_id
packet[3] = sequence
# calculate checksum
checksum = 0_u32
packet.each do |byte|
checksum += byte
end
checksum += checksum >> 16
checksum = checksum ^ 0xffff_ffff_u32
packet[1] = checksum.to_u16
# convert packet to 8 bit words
slice = Bytes.new(PACKET_LENGTH_8)
eight_bit_packet = packet.map do |word|
[(word >> 8), (word & 0xff)]
end.flatten.map(&.to_u8)
eight_bit_packet.each_with_index do |chr, i|
slice[i] = chr
end
# send request
address = Socket::IPAddress.new host, 0
socket = IPSocket.new Socket::Family::INET, Socket::Type::DGRAM, Socket::Protocol::ICMP
socket.send slice, to: address
# receive response
buffer = Bytes.new(PACKET_LENGTH_8 + IP_HEADER_SIZE_8)
count, address = socket.receive buffer
length = buffer.size
icmp_data = buffer[IP_HEADER_SIZE_8, length-IP_HEADER_SIZE_8]
end
ping
最佳答案
事实证明,Linux(以及 docker 的扩展名)并未提供与 macOS 对 DGRAM 套接字相同的权限。将套接字声明更改为 socket = IPSocket.new Socket::Family::INET, Socket::Type::RAW, Socket::Protocol::ICMP
允许套接字在 docker 下连接。
在非 root 上下文中运行该程序还需要一点。因为原始套接字仅限于 root,二进制文件也必须发布正确的 capability用于访问原始套接字,CAP_NET_RAW
。但是,在 docker 中,这不是必需的。通过运行 sudo setcap cap_net_raw+ep bin/ping
,我能够让程序在 super 用户上下文之外运行。 This is a decent primer on capabilities and the setpcap command
MacOS 不使用相同的权限系统,因此 setcap
只是一个无法识别的命令。因此,为了让上述代码在没有 super 用户上下文的情况下在 macOS 上成功编译和运行,我将套接字创建代码更改为:
socket_type = Socket::Type::RAW
{% if flag?(:darwin) %}
socket_type = Socket::Type::DGRAM
{% end %}
socket = IPSocket.new Socket::Family::INET, socket_type, Socket::Protocol::ICMP
如果需要,在构建过程的其他地方应用 CAP_NET_RAW
功能以在 linux 中使用。
通过这些更改,我没有看到任何需要更改 seccomp 或 apparmor 以运行该程序的默认 Docker 附带的。
关于sockets - 从 docker 容器中打开 DGRAM 套接字失败(权限被拒绝),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47370366/
我有在计算机之间发送 dgram 消息的工作代码,但我正在尝试用 Blowfish 加密它们。当我尝试在两台小端机之间发送消息时它工作正常,但是当我尝试将小端发送到大端(或相反)时,它无法正确解密。
我有一个用 node.js 编写的 UDP dgram 套接字服务器。 这是来自 server.js 的代码片段 var PORT = 50000; var HOST = '0.0.0.0';
我想为 dgram 实现超时NodeJS 中的套接字。我四处寻找像 socket.setTimeout 这样的原生 udp 解决方案。在 net图书馆。 这是我的想法: const Dgram = r
我正在使用的 UDP 服务器遇到一个奇怪的问题。收到的第一个 udp 数据包没有关于数据包来源的信息。随后的 udp 数据包似乎都没有问题,并正确显示了接收数据包的 ip 地址。我不知道是什么导致了这
有没有办法为 dgram UDP 套接字设置编码,与在 TCP/IP 网络套接字中设置编码相同? 我正在寻找与网络中的方法 socket.SetEncoding 等效的方法.Socket类。 最佳答案
我已经安装了一个模板 Ionic 2 应用程序并想添加 NPM 包 bonjour 像这样在我的组件中安装并包含包之后: var Bonjour = require('bonjour'); var b
这更多是一种观察,也是对处理这种情况的最佳方法的建议。 我有两个线程,一个只是泵入数据,另一个接收数据并在发送另一个套接字之前做很多工作。两个线程都通过域套接字连接。这里使用的协议(protocol)
我是 UDP 套接字的新手,我以前使用过 TCP。看来我的客户端无法连接到我的服务器,但我不知道问题出在哪里。 当我运行我的服务器时,它看起来一切正常。编译运行没有问题,等待客户端消息。 另一方面,客
我正在运行一个应用程序,它构建 ICMP ECHO 请求并将其发送到几个不同的 IP 地址。该应用程序是用 Crystal 编写的。尝试从 crystal docker 容器中打开套接字时,Cryst
Node -v => v5.5.0 commande => "watchify src/js/app.js --extension=.jsx -t [ babelify --presets [ es2
我正在使用 Node 的内置数据报 UDP 套接字进行简单的 UDP“发送”: http://nodejs.org/docs/v0.3.1/api/dgram.html 消息的目的地是一个域名,在传输
我正在使用 Node.js 0.6.9,并且正在尝试发送数据报广播包。代码: var sys = require('util'); var net = require('net'); var dgra
我尝试了各种版本的 Nodejs 的数据报套接字模块的发送功能: var dgram = require('dgram'); var client = dgram.createSocket('udp4
The docs (以及我看过的许多库)似乎表明您每次发送时都关闭客户端: var dgram = require('dgram'); var message = new Buffer("Some b
如何编写测试来验证我的应用程序是否通过 dgram 绑定(bind)到特定的 UDP 端口?下面是我想要测试的代码片段: var dgram = require('dgram'); v
是否可以获取向我的 Node 应用程序发送 UDP 请求的客户端的 IP 地址? 该应用程序在我的本地网络中使用,我想根据地址过滤请求。当我在获取消息事件时尝试使用 rinfo 对象中提供的地址时,我
我正在使用 socket.io 和 dgram Node 库通过 Node 将 UDP 消息从一个程序发送到浏览器。 代码看起来就像 socket.io 示例 var dgram = require(
我正在尝试运行下面提到的 Node js 应用程序 https://github.com/joyent/node/issues/2194 var util = require("util"), d
我正在使用 Nodejs 的 dgram 模块运行一个简单的 UDP 服务器。相关代码很简单: server = dgram.createSocket('udp4'); serve
我最近通过 npm 安装 n 然后调用 n stable 将我的 node.js 版本从 0.10.31 升级到 4.0.0。 有了新的 Node 版本,我现有的代码就崩溃了。 这段代码: var d
我是一名优秀的程序员,十分优秀!