I have a jersey/grizzly web service running on an Azure VM with Ubuntu server 14.04 LTS. I can access the web service from within the machine with curl, but from outside the machine the request just times out.
That is, I can do this curl line:
curl -X POST http://example.cloudapp.net:80/resource/path --data "text=´Mario"
and get a response from within the shell of the VM, but not from my windows console, or another VM in the same Azure datacenter.
I start the Grizzly web server on port 9998 in my Main.java:
public class Main {
public static final URI BASE_URI = UriBuilder.fromUri("http://0.0.0.0/").port(9998).build();
protected static SelectorThread startServer() throws IOException {
final Map<String, String> initParams = new HashMap<String, String>();
initParams.put("com.sun.jersey.config.property.packages", "mypackage");
SelectorThread threadSelector = GrizzlyWebContainerFactory.create(BASE_URI, initParams);
return threadSelector;
}
public static void main(String[] args) throws IOException {
SelectorThread threadSelector = startServer();
System.in.read();
threadSelector.stopEndpoint();
}
}
And I can see it listening with netstat -a:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:9998 *:* LISTEN
I have set up an Azure endpoint so that I can access the webservice on the VM, making the translation between the inner port 9998 and the outer port 80.
There are no ACL rules on the endpoint, so the default is to let everything through.
My iptables in the VM is set to let everything through:
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:68
My theory is that the problem is outside the virtual machine, but I don't know where to begin. Does anyone have an idea about how to solve this or how to proceed with the troubleshooting? Please ask, if there is anything else you need. One thing that might help is if I could get the access attempt logs for the Azure endpoints, but I don't know how to get them.
Related
I have an HTTP trigger / Azure function that tries to write to a service bus. WHen I try to trigger locally via POSTMAN, this is the error I get in VSCODE:
[2022-02-25T17:47:27.426Z] Executed 'mytestmethod' (Failed, Id=61291e4d-92de-4306-93ba-c0902dbaae3b, Duration=96242ms)
[2022-02-25T17:47:27.428Z] System.Private.CoreLib: Exception while executing function: O3mWorkspaceNotifications. System.Private.CoreLib: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ErrorCode: TimedOut (ServiceCommunicationProblem). System.Private.CoreLib: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
So I found this article: https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-troubleshooting-guide
And I've tried to add a Firewall rule to open up everything incoming / outgoing to my specific ip address. To get the ip address I ran this command in powershell:
PS C:\Users\me\.azure> tnc myresourcegroup-bus.servicebus.windows.net -port 5671
WARNING: TCP connect to (111.11.1.11 : 5671) failed
WARNING: Ping to 111.11.11.11 failed with status: TimedOut
ComputerName : myresourcegroup-bus.servicebus.windows.net
RemoteAddress : 111.11.11.11
RemotePort : 5671
InterfaceAlias : Ethernet
SourceAddress : 10.111.11.111
PingSucceeded : False
PingReplyDetails (RTT) : 0 ms
TcpTestSucceeded : False
I added both an incoming and an outgoing FW rule on my local windows 10 development box. I added a "custom rule" that allows all program, all ports for that specific IP address.
Then I tried to telnet to my azure service bus but it blows up in my face: (tried telnet via ubuntu subsystem on windows 10)
admin#CAMXL0332ZPD:/mnt/c/Users/me$ telnet 111.11.11.11 5671
Trying 111.11.11.11...
telnet: Unable to connect to remote host: Resource temporarily unavailable
Not sure what else to check.
Any tips would be appreciated.
EDIT 1
This is what my code looks like right now:
public class mywidgetsclass {
[FunctionName("widgetsNotifications")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "mywidgets/sbnotification")] HttpRequest req,
[ServiceBus("widgets", ServiceBusEntityType.Queue, Connection = "WidgetsServiceBus")] IAsyncCollector<WidgetsNotification> outputQueue,
ILogger log)
{
log.LogInformation($"WidgetsNotificationPOST method invoked");
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var widgetsNotification= JsonConvert.DeserializeObject<WidgetsNotification>(content);
await outputQueue.AddAsync(widgetsNotification);
var response = new {widgetsNotification, QueuedResult=true};
return new OkObjectResult(response);
}
}
It appears that your network environment is not allowing traffic for ports 5671 and 5672. This is often resolved by configuring the ServiceBusClient to use the web sockets transport which uses port 443 (default HTTPS port):
var options = new ServiceBusClientOptions
{
TransportType = ServiceBusTransportType.AmqpWebSockets
};
var client = new ServiceBusClient("<< CONNECTION STRING >>", options);
For Azure Functions configuration of the Service Bus trigger and bindings, the transport can be specified in host.json when using v5.0+ of the Microsoft.Azure.WebJobs.Extensions.ServiceBus package.
{
"extensions": {
"serviceBus": {
"transportType" : "amqpWebSockets"
}
}
I am implementing a transparent TCP/UDP proxy for all ports (1-65535) on a Raspberry Pi on LAN. I am currently testing routing TCP packets with destination port 80 to the Raspberry Pi. The idea is that one interface (cf "proxy ip") captures incoming traffic and the other (cf "server ip") sends it to the internet and processes it before the original one sends the response to the client. The necessary routing on the router is done via
iptables -t mangle -A PREROUTING -p tcp -s SERVER_IP -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -s SOME_TEST_CLIENT_IP --dport 80 -j MARK --set-mark 3
ip rule add fwmark 3 table 2
ip route add default via PROXY_IP dev br0 table 2
inspired by this page. This architecture implies a one-to-one port mapping between external IP addresses and the Raspberry PI's proxy interface. The packets arrive with the correct port and destination on the Raspberry Pi (verified with tcpdump), however the proxy doesn't accept the connections: no SYN-ACK is sent for the incoming SYN's. The proxy listening sockets are mainly configured with
const char PROXY_IP_ADDR[] = "192.168.1....";
const char SERVER_IP_ADDR[] = "192.168.1....";
...
struct sockaddr_in saProxy = {0};
saProxy.sin_family = AF_INET;
saProxy.sin_port = htons(80);
inet_pton(AF_INET, PROXY_IP_ADDR, &(saProxy.sin_addr.s_addr));
int enable = 1;
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(-1 == setsockopt(sockfd, SOL_IP, IP_TRANSPARENT, (const char*)&enable, sizeof(enable)) /*error processing*/;
if(-1 == bind(sockfd, (sockaddr*)&saProxy, sizeof(saProxy))) /* error processing*/;
if(-1 == listen(sockfd, 1)) /* error processing*/;
Followed by epoll_ctl() and epoll_wait(). The proxy has been tested with sending HTTP requests and NBNS traffic directly to PROXY_IP without the aforementioned routing in place and it is receiving and processing these connections properly.
Unfortunately, I have found very little documentation or examples related to IP_TRANSPARENT. My original Windows-related question before I could do any testing on Linux. Kernel version is 4.1.13-v7+. How can I achieve this type of proxying?
Edit: I believe I may be missing some routing settings on the Raspberry Pi such as perhaps described here, but I have very little experience with iptables so I don't quite understand the rules described there, although I have read that non-local traffic is rejected by the kernel unless some specific routing is set up since it doesn't know about sockets.
I have also tested binding directly to an external IP address and attempted to listen for packets with this destination address, but the symptoms remain unchanged.
The solution was pretty simple actually. In order to use IP_TRANSPARENT for this purpose, you need to have a single listening socket bound to some port X. Then you need to setup the following rules, assuming you want to redirect ALL traffic going through any (I believe) interface, excluding traffic generated for/by the proxy itself. Here the proxy's IP is 192.168.1.100 and we redirect TCP to port 82 and UDP to port 83.
iptables -t mangle -A PREROUTING ! -d 192.168.1.100 -p tcp -j TPROXY --on-port 82 --on-ip 0.0.0.0 --tproxy-mark 0x1/0x1
iptables -t mangle -A PREROUTING ! -d 192.168.1.100 -p udp -j TPROXY --on-port 83 --on-ip 0.0.0.0 --tproxy-mark 0x1/0x1
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
Linux has a special mechanism called tproxy for this.
For TCP
From here on, the socket returned by accept is automatically bound to the original destination and connected to the source, so using it for transparent proxying requires no more work on this side of the proxy.
In order to get the original destination of the socket as a sockaddr_in structure, call getsockname() on the socket returned by accept() as usual.
For UDP
To be able to get the original destination, on the UDP socket, set this option before binding:
int enable = 1;
setsockopt(sockfd, SOL_IP, IP_RECVORIGDSTADDR, (const char*)&enable, sizeof(enable));
Then, to receive the data and get the original destination
char cmbuf[100];
unsigned char bytes[16*1024];
sockaddr_in srcIpAddr, dstIpAddr;
int dstPort;
iovec iov;
iov.iov_base = bytes;
iov.iov_len = sizeof(bytes)-1;
msghdr mh;
mh.msg_name = &srcIpAddr;
mh.msg_namelen = sizeof(sockaddr_in);
mh.msg_control = cmbuf;
mh.msg_controllen = 100;
mh.msg_iovlen = 1;
mh.msg_iov = &iov;
int res = recvmsg(sock, &mh, 0);
sem_post(&udpSem); //I use a semaphore to indicate when incoming data is read and socket is ready for new datagram to be processed
for(cmsghdr *cmsg = CMSG_FIRSTHDR(&mh); cmsg != NULL; cmsg = CMSG_NXTHDR(&mh, cmsg))
{
if(cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_ORIGDSTADDR) continue; //normally we use IP_PKTINFO if not using tproxy, but this would yield 192.168.1.100:83 in the example
std::memcpy(&dstIpAddr, CMSG_DATA(cmsg), sizeof(sockaddr_in));
dstPort = ntohs(dstIpAddr.sin_port);
}
Then, if we want to reply to the datagram, we need to make a new UDP socket (as UDP is connectionless) and bind it to the original destination of the datagram, stored in dstIpAddr. I had some trouble here as I first tried using IP_FREEBIND, but this option does not seem to work for sending data through UDP, I think it is only intended for TCP listening sockets, so we use IP_TRANSPARENT again before binding to be able to bind to a non-local address.
Hi All,
I want to create a JSP page where I will ask user to give the source host and port and also destination host and port.
Following combination of source and destination OS is possible
Unix->Unix/Windows/zOS Windows-> Unix/Windows/zOS zOS ->
Unix/Windows/zOS
With these inputs I want to connect to the source server and fire this command telnet $ip $port to the destination. If the telnet connectivity is successful it should return success and else error.
I want to create the logic non-interactive that it should not require any password to login the source for checking telnet connectivity.
Is there any such library or any mechanism available so that I could make this feasible?
Why not use Apache Commons Net?
TelnetClient telnet = new TelnetClient();
try {
telnet.connect("rainmaker.wunderground.com", 3000);
} catch(IOException e) {
// failed
} finally {
telnet.disconnect();
}
Good day everyone!
I am making a DHCP Server for a project. I tried it in Windows and it worked. Now, I need to make it work on Linux. I used the same code and it can listen packets coming from port 67. However, every time I am about to send packets to the machine in KVM (Kernel Virtual Machine), I get an error at line containing "datagramsocket.send(response)" saying that Network is Unreachable. Btw, I am using a centOS as host and another centOS as guest machine. Bridge connection and firewall is disabled. How could I fix this problem? I am clueless.
Thanks in advance! :)
I used a dhcp4java API and here's a portion of my code:
if (replypacket != null){
InetAddress add = replypacket.getAddress();
int port = replypacket.getPort();
byte[] buf = replypacket.serialize();
DatagramPacket response = new DatagramPacket(buf, buf.length, add, port);
datagramsocket.send(response);
}
I am trying to get a simple WebSocket server going using SignalR, OWIN and Azure Worker Roles.
WorkerRole.cs:
public class WorkerRole : RoleEntryPoint
{
public override void Run()
{
string url = "http://" + RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["MyEndpoint"].IPEndpoint;
using (WebApp.Start<Startup>(url))
{
Trace.WriteLine(String.Format("Server running on {0}", url));
}
while (true)
{
}
}
/* ... */
}
Startup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
MyHub.cs:
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
The Endpoint "MyEndpoint" is defined in the Service as http, public and private port 5001.
After starting the service, it shows up under Azure Compute Emulator as running on 5001. However, if I try to connect to ws://127.0.0.1:5001/signalr (or just ws://127.0.0.1:5001) there is no response. I am using two different web socket clients for this purpose (both are Chrome plugins and they both worked fine using other WebSocket servers).
Questions:
1) Is there anything obviously wrong with my setup?
2) Do I need to use the SignalR JS client libraries to connect to the SignalR server, or should any vanilla client implementing the WebSocket protocol be able to connect?
I know this is a bit of an old post but just in case someone needs it...
1) There are two problems you need to address.
First of all, Start method in:
using (WebApp.Start<Startup>(url))
{
Trace.WriteLine(String.Format("Server running on {0}", url));
}
returns an IDisposable (hence the using(...){} block) means it is immediately disposed after creation since execution continues right passed Trace.Writeline(...) without pause.
It's also a bit tricky running these things under the Azure Compute Emulator for a few reasons, mainly because it remaps ports to avoid collisions. If you open up a command prompt and run
netstat -a
you'll find that you have open ports (listening) looking something like this (in my case I'm using port 81):
TCP 127.0.0.1:82 MyComputer:0 LISTENING
TCP 127.0.0.3:81 MyComputer:0 LISTENING
In the general console ouput of Visual Studio, you'll also most likely see something like
"Windows Azure Tools: Warning: Remapping private port 81 to 82 in role 'MyRoleThingy' to avoid conflict during emulation."
This all means that in order to connect to the server you're hosting using your worker role, you'll have to connect to port 82 instead of 81 (probably 5002 in your case).
2) If you implement the protocol, anything should work I think. Managing an initial connection on the port should always work.