How to call a IPv6 REST service over AWS Lambda - java

I've got an Alexa Skill hosted in AWS Lambda which uses AsyncHttpClient to call an IPv6 REST service under the following EXAMPLE URL:
http://[2a12:5375:4151:2300:1353:a632:5f4e:c232]:4711/rest/test
Now my problem is, that I always get the following exception:
ava.util.concurrent.ExecutionException: java.net.ConnectException: Protocol family unavailable
If I check the IP address which is assigned to the underlying server or the application?, I get the following address (also example):
ip-10-23-56-1.eu-west-1.compute.internal: 10.23.56.1
So I think, because I am using an IPv6 while the system uses IPv4, I can't get it working?
I can call my REST service from another server successfully.
I am also using the following system properties:
System.setProperty("java.net.preferIPv6Addresses", "true");
System.setProperty("java.net.preferIPv4Stack", "false");
Is there any solution to provide a 'tunnel' over the IPv4 underlying system to tunnel the IPv6 address to call the REST service? Or is there any simpler solution?

The error Protocol family unavailable means that the protocol (in this case IPv6) is not available or not configured on the system on which your code is running.
In the case of AWS, the only thing you can do about this is to complain and hope they eventually roll out IPv6 support to services which don't yet have it.

After quite an extensive research and tests the word is: IPv6 is not available for Lambda. This goes a bit further if you run your Lambda functions inside a VPC.
If your function is associated with a subnet that includes IPv6 CIDR then no amount of correct config will get your Lambda to access external resources.
You will be able to do API calls to some of the AWS resources available as VPC endpoints. This includes services like S3 and Dynamo, they will get an internal IP within your VPC. Services like SQS are not supported under VPC endpoint so will get external resolution.
Any service or external API call that goes outside your VPC will fail with IPv6 CIDR. The only way to go around this is to remove IPv6 CIDR from the subnet or create a dedicated subnets just for your Lambda functions.
We have opted for the latter option and all is working great with appropriate VPC security and routing policies applied.

Related

How to enable IP access filter on Spark Worker?

I have a java application that starts up a spark worker:
Worker.startRpcEnvAndEndpoint(args.host(), args.port(), args.webUiPort(), args.cores(), args.memory(), args.masters(), args.workDir(), scala.Option.empty(), conf);
(see https://books.japila.pl/spark-standalone-internals/Worker/#externalshuffleservice)
I would now like to set up an IP access filter so that I have a hard coded list of IP addresses that can access this service.
Is there a way to configure the Java program above to provide such an IP access filter?
I am not aware of Spark internal networking, but from a server bind-address perspective, the best you can do is to isolate the bind address on a specific interface/subnet - this would start with your args.host()
If you want to restrict to specific IPs within that subnet, you'll need to work with the OS firewall, maybe managing that from code as well, but not with the Spark libraries.
Then going further - restricting to certain clients, rather than machines, you could provide certificates into certain machines, or users, or otherwise encode IP addresses into some auth protocol, then enforce ACL policies for Spark. Perhaps you can use Kerberos for this, too

Custom DNS Resolver in JaxRS?

I'm developing a Java application (launched by Tomee) which needs to call, using JaxRS, an HTTPS server with its hostname, but the hostname is not resolved by the DNS.
In practice, my application creates a VM using Openstack API, so the IP address has been dynamically allocated during the lifetime of the application (which is why it's not solved by the DNS).
But I have to call an HTTPS server running on that VM, for which the certificate was signed using a given hostname, so I MUST call it with https://hostname, and not with https://ip_address...
I am not allowed to "play" with TLS configuration, by (for example) disabling Common Name check, so the only solution I see is to be able to "intercept" a DNS resolution request, to provide the good IP address to use.
The How to override DNS in HTTP connections in Java page shows a solution using Apache HttpClient - however, our microservice was entirely built on JaxRS, and I failed to find a way to do the same thing with it.
The client used is the v3.2.2 version of org.apache.cxf:cxf-rt-rs-client, provided by the Tomee we are based on.
Thanks for your attention!

How configure aws-ec2 Instance to run playframework 1.2.7 application

I have deployed our playframework 1.2.7 web application to aws-ec2 ubuntu instance. The started the application on port 8081 since 80 or 8080 complains about not able to bind to those ports. How can I configure the ubuntu instance either througth the aws security group or on ubuntu itself so that I wouldn't have to add the port 8081 to the end of the public url or the public ip provided by aws.
ie I don't want do this:
example.com:8081 / ip4:8081
But I just want to use:
example.com / ip4
to access the application.
Please I need help on this.
The problem is that on Ubuntu ports < 1024 are privileged. This means that normal users can do nothing with it. To start play on port 80 you could simply start it as root user. Anyway it's not a best practice to start webserver as root due to possible security issues.
I'd suggest to start it on whatever non-privileged port you want, as normal user, and make use of an Elastic Load Balancer (ELB) to redirect all inbound traffic on port 80(or 443 for instance) to your play port. You can accomplish this simply using AWS web interface, when creating an ELB
So users will reach your play instance calling ELB on port 80 using Amazon auto-assigned dns name.
Example flow:
User browser --> http://your-elb-dns-name.com --> your_play_server_ip:8081
Just make sure that the Security Group associated to your play server instance will accept inbound traffic on 8081 from your ELB (you can identify your ELB using the amazon id assigned during its creation)
Another great advantage of using this ELB approach is that you can use it as reverse proxy to hide your ec2-instance(s) ip(s) to the internet. In fact, if you use ELB you could also avoid assignin a public ip to your ec2 instance during creation. ELB doesn't need to know a public ip beacuse it will have access to the Virtual Private Cloud (VPC) in which your ec2 instance was started
Another possible approach, if you don't want to use ELB, is to install NGINx or Apache on your ec2 instance to act as reverse proxy, but I think you should make use of Amazon web services to accomplish that. You may want to use an internal NGINX or Apache reverse proxy if you need to hide a particular resource of your play server to the internet.
https://aws.amazon.com/it/elasticloadbalancing/

How to automatically discover Web Service by scanning LAN C#

I am consuming a web service (which was written in Java) in C#. The web service is available in LAN but at compile time I don't know the address of the server. I need to scan the network to find the IP address of the computer where the web service is hosted. I do know the port though.
At the moment, I have the following code, which is supposed to give me a list of all active IP address and then I am planning trying to find out if the write port is open, and as soon as I find a computer where the right port is open, I will know the IP address of the server, am I thinking along the correct lines?
List<IPAddress> ipList = new List<IPAddress>();
IPGlobalProperties network = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] connections = network.GetActiveTcpConnections();
foreach (TcpConnectionInformation ipEnds in connections)
{
ipList.Add(ipEnds.LocalEndPoint.Address);
Console.WriteLine(ipEnds.LocalEndPoint.Address.ToString());
}
The web-services must have define the way you can discovered, for example you throw a broadcast with a specific soap message, in that way al services that matched with that soap message must response to you.
Also you can use DiscoveryClient class (C#) to discovered services, it allow you define scopes and other specifications.
Is your C# application that consumes the data at a static location?
At build time, you could modify your Java application to reach out to the consuming service to provide an accurate location. This should reduce extra noise on your network. This should also reduce time that your application will hang attempting to connect to each IP address on the specified port.

Best way to tunnel RMI over HTTP

I'm looking for a secure way to tunnel RMI traffic.
In My application(java Webstart) i must assume that the only port that is open is port 80.
I have the looked att socketfactories for rmi but do i really need a proxy then.
I need to do all my tunneling on the client side.
The only firewall i am trying to get past is on the client side.
I'm not able to open 1099 with port ranges above.
Would be nice to see some implementations.
Thanks!
Port 1099 was reserved for RMI at IANA in about 1995. There is no reason for it not to be open for outbound access in the client-side firewall.
RMI can be made to use fixed port numbers by supplying a port number when constructing (super(port)) or exporting (exportObject(object, port)). Better still, if you create the Registry within the server JVM via LocateRegistry.createRegistry(), all subequently exported remote objects will use that port unless they specify a different port or they use a server socket factory.
BUT ... RMI already includes HTTP tunneling 'out of the box'. No external solution required. You have to deploy the RMI-Servlet provided with the JDK, at the server end.
(a)
although not the newest fashion, exposing remote services with Hessian and Burlap seems to be a simple solution to avoid problem working across firewalls: http://hessian.caucho.com/doc/
see sample code for the server and client side:
http://www.javatpoint.com/spring-remoting-by-hessian-example
(b) or consider using Spring HttpInvokder (see some sample code here: http://www.javatpoint.com/spring-remoting-by-http-invoker-example)
HttpInvokder provides more customization options through the RemoteInvocationFactory, RemoteInvocationExecutor and HttpInvokerRequestExecutor strategies (for example, to add custom context information (such as user credentials) to the remote invocation, or using java’s built-in object serialization etc.), see:
http://docs.spring.io/spring-framework/docs/2.0.x/api/org/springframework/remoting/support/RemoteInvocationFactory.html

Categories