Open some custom inbound ports e.g. 8077 by using

2019-08-18 05:35发布

问题:

I am launching one windows instance in AWS(Amazon) using Java and trying to open few inbound ports like 445, 555, 9089, 8077 for my work.
I have also tried using Security groups port opening but it is only opening the inbound ports at security group level, not at the system level.
Provide me some solution so that I can open either before launch itself or after launch is also fine.
Here is my sample code.

package com.corenttech.engine.shift;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
import com.amazonaws.services.ec2.model.AvailabilityZone;
import com.amazonaws.services.ec2.model.CreateKeyPairRequest;
import com.amazonaws.services.ec2.model.CreateKeyPairResult;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
import com.amazonaws.services.ec2.model.DescribeImagesResult;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
import com.amazonaws.services.ec2.model.Image;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.IpPermission;
import com.amazonaws.services.ec2.model.KeyPair;
import com.amazonaws.services.ec2.model.Placement;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.RunInstancesResult;
import com.amazonaws.services.ec2.model.SecurityGroup;
import com.amazonaws.services.ec2.model.StartInstancesRequest;
import com.amazonaws.services.ec2.model.StopInstancesRequest;
import com.amazonaws.services.ec2.model.Tag;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;
import com.amazonaws.services.ec2.model.TerminateInstancesResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;

public class AwsConnection {

static AmazonEC2Client ec2;
static Logger logger = Logger.getLogger(AwsConnection.class);
static String Group_name;

private AwsConnection() {

}

public static void main(String[] args) throws Exception {
    String credentialsString;
    AmazonCredentials cred = new AmazonCredentials();
    cred.setAccessKeyId("accesskey");
    cred.setSecretKey("secretKey");


    credentialsString = "accessKey = " + cred.getAccessKeyId() + "\n";
    credentialsString += "secretKey = " + cred.getSecretKey();
    logger.info("credentialString :" + credentialsString);

    InputStream inpStrm = new ByteArrayInputStream(credentialsString.getBytes());
    AWSCredentials credentials = new PropertiesCredentials(inpStrm);
    ec2 = new AmazonEC2Client(credentials);

    try {

        AuthorizeSecurityGroupIngressRequest secrtyGrp = createSecurityGroup();
        List<String> groupName = updatePortToSecurityGroup(cred, secrtyGrp);

//            listAvailableZones();
//            getAvailableImages();
//            getRunningInstances();

        /* Launching a new AMI instance*/
        List<String> runninginstanceIDs = createAMInstances("ami-76f0061f", 1, 1, "Maas", "t1.micro", "us-east-1a", groupName);


        String runningInstanceID = runninginstanceIDs.iterator().next();
        logger.info("New instance created successfully : " + runningInstanceID);

        TimeUnit.SECONDS.sleep(60);
        createTagName(runningInstanceID);
        TimeUnit.SECONDS.sleep(1);
        getRunningInstances();

    } catch (AmazonServiceException ase) {
        logger.info("Caught Exception: " + ase.getMessage());
        logger.info("Reponse Status Code: " + ase.getStatusCode());
        logger.info("Error Code: " + ase.getErrorCode());
        logger.info("Request ID: " + ase.getRequestId());

    }

}

public static AuthorizeSecurityGroupIngressRequest createSecurityGroup() {
    Group_name = "group_test" + 1; //name of the group
    CreateSecurityGroupRequest r1 = new CreateSecurityGroupRequest(Group_name, "test group"); // this is security group description
    ec2.createSecurityGroup(r1);
    AuthorizeSecurityGroupIngressRequest r2 = new AuthorizeSecurityGroupIngressRequest();
    r2.setGroupName(Group_name);
    return r2;
}

public static List<String> updatePortToSecurityGroup(AmazonCredentials cred, AuthorizeSecurityGroupIngressRequest secrtyGrp) {
    logger.info("<<Amazon updatePortToSecurityGroup start>>");
    String protocol = "tcp";
    int port = 8077;

    IpPermission perm1 = new IpPermission();
    perm1.setIpProtocol(protocol);
    perm1.setFromPort(port);
    perm1.setToPort(port);
    List<String> ipRanges = new ArrayList<>();
    ipRanges.add("0.0.0.0/0");
    perm1.setIpRanges(ipRanges);

    IpPermission permission2 = new IpPermission();
    permission2.setIpProtocol("tcp");
    permission2.setFromPort(445);
    permission2.setToPort(445);
    List<String> ipRanges2 = new ArrayList<>();
    ipRanges2.add("0.0.0.0/0");
    permission2.setIpRanges(ipRanges2);

    IpPermission permission3 = new IpPermission();
    permission3.setIpProtocol("tcp");
    permission3.setFromPort(555);
    permission3.setToPort(555);
    List<String> ipRanges3 = new ArrayList<String>();
    ipRanges3.add("0.0.0.0/0");
    permission3.setIpRanges(ipRanges3);

    IpPermission permission4 = new IpPermission();
    permission4.setIpProtocol("tcp");
    permission4.setFromPort(8080);
    permission4.setToPort(8080);
    List<String> ipRanges4 = new ArrayList<>();
    ipRanges4.add("0.0.0.0/0");
    permission4.setIpRanges(ipRanges4);

    IpPermission permission5 = new IpPermission();
    permission5.setIpProtocol("tcp");
    permission5.setFromPort(3389);
    permission5.setToPort(3389);
    List<String> ipRanges5 = new ArrayList<>();
    ipRanges5.add("0.0.0.0/0");
    permission5.setIpRanges(ipRanges5);

    IpPermission permission6 = new IpPermission();
    permission6.setIpProtocol("tcp");
    permission6.setFromPort(9089);
    permission6.setToPort(9089);
    List<String> ipRanges6 = new ArrayList<>();
    ipRanges6.add("0.0.0.0/0");
    permission6.setIpRanges(ipRanges6);

    IpPermission permission7 = new IpPermission();
    permission7.setIpProtocol("tcp");
    permission7.setFromPort(80);
    permission7.setToPort(80);
    List<String> ipRanges7 = new ArrayList<>();
    ipRanges7.add("0.0.0.0/0");
    permission7.setIpRanges(ipRanges7);

    IpPermission permission8 = new IpPermission();
    permission8.setIpProtocol("tcp");
    permission8.setFromPort(443);
    permission8.setToPort(443);
    List<String> ipRanges8 = new ArrayList<>();
    ipRanges8.add("0.0.0.0/0");
    permission8.setIpRanges(ipRanges8);

    IpPermission permission9 = new IpPermission();
    permission9.setIpProtocol("tcp");
    permission9.setFromPort(23);
    permission9.setToPort(23);
    List<String> ipRanges9 = new ArrayList<>();
    ipRanges9.add("0.0.0.0/0");
    permission9.setIpRanges(ipRanges9);

    List<IpPermission> permissions = new ArrayList<>();
    permissions.add(perm1);
    permissions.add(permission2);
    permissions.add(permission3);
    permissions.add(permission4);
    permissions.add(permission5);
    permissions.add(permission6);
    permissions.add(permission7);
    permissions.add(permission8);
    permissions.add(permission9);

    secrtyGrp.setIpPermissions(permissions);

    ec2.authorizeSecurityGroupIngress(secrtyGrp);
    List<String> groupName = new ArrayList<>();
    groupName.add(Group_name);

    logger.info("<<Amazon updatePortToSecurityGroup end>>");
    return groupName;
}

public static List<SecurityGroup> findAllSecurityGroups() {
    DescribeSecurityGroupsRequest securityRequest = new DescribeSecurityGroupsRequest();
    DescribeSecurityGroupsResult securityDescription = ec2.describeSecurityGroups(securityRequest);
    return securityDescription.getSecurityGroups();
}


/**
 * Create one or more running instances of a given AMI. If you want to lunch
 * a machine in the amazon cloud this is the method that you are looking
 * for. The key method is RunInstancesResult runInstancesRes =
 * ec2.runInstances(request); that return a unique id of the reservation for
 * retrieving the running instances. By the way if you do that you will have
 * to query the amazon APIs, it will be slower and will cost you but is good
 * to know that this information will be always there.
 *
 * @param amiId unique ID of the machine
 * @param min minimum number of machines
 * @param max maximum number of machines that you want to run
 * @param keyPairName unique id of the key pair that will be used for
 * running an instance
 * @param insType type of instance (i.e. m1.small)
 * @param availabilityZone where the instance should run
 * @param groupName
 * @return List of unique ID of running instances
 * @throws AmazonServiceException something wrong in Amazon
 * @throws Exception some communication failure
 */
public static List<String> createAMInstances(String amiId, int min, int max,
        String keyPairName, String insType, String availabilityZone, List<String> groupName)
        throws AmazonServiceException {

    List<String> runninginstanceIDs = new ArrayList<>();

    RunInstancesRequest request = new RunInstancesRequest(amiId, min, max);
    /*Chose the type i.e. m1.small*/
    request.setInstanceType(insType);
    request.setKeyName(keyPairName);// assign Keypair name for this request
    request.setSecurityGroups(groupName);

    // Chose the zone
    Placement p = new Placement();
    p.setAvailabilityZone(availabilityZone);
    request.setPlacement(p);

    RunInstancesResult runInstancesRes = ec2.runInstances(request);
    String reservationId = runInstancesRes.getReservation().getReservationId();

    //Getting the list of running instances according with our request
    Reservation reservation = runInstancesRes.getReservation();
    List<Instance> instances = reservation.getInstances();
    if (!instances.isEmpty()) {
        Iterator<Instance> instIterator = instances.iterator();
        int count = 0;
        //getting the descriptions of the instances
        while (instIterator.hasNext()) {
            Instance runningInst = instIterator.next();
            logger.info("We just start the Instance " + count + " UniqueID: "
                    + runningInst.getInstanceId() + " ImageId " + runningInst.getImageId()
                    + " type: " + runningInst.getInstanceType() + " Started by "
                    + runningInst.getKeyName() + " Status: " + runningInst.getState().toString());
            //Unique ID of the image that is running
            String uniqueID = runningInst.getInstanceId();
            runninginstanceIDs.add(uniqueID);
            count++;
        }
    }

    //Optionally you can use the unique id of the reservation for retrieving the running instance. 
    //if you do that you will have to query the amazon APIs, it will be slower and will cost you  
    //but is good to know that this information will be always there.
    logger.info("reservation ID of the executed transaction: " + reservationId);
    return runninginstanceIDs;
}

/**
 * Terminate (kill) a given running instance. Note that the method returns
 * when you move from "your previous state" to "terminating" and not when
 * the machine is actually terminated.
 *
 * @param instanceId unique ID of the running instance.
 * @throws AmazonServiceException something wrong in Amazon
 * @throws AmazonServiceException some communication failure
 */
public static void terminateAMI(String instanceId) throws AmazonServiceException {
    TerminateInstancesRequest rq = new TerminateInstancesRequest();
    rq.getInstanceIds().add(instanceId);
    TerminateInstancesResult rsp = ec2.terminateInstances(rq);
    logger.info("Insance successfully terminated : " + rsp.toString());
}

public static void createTagName(String runningInstanceID) {

    List<String> resources = new LinkedList<>();
    List<Tag> tags = new LinkedList<>();
    Tag nameTag = new Tag("Name", "Ankit_Shift");

    resources.add(runningInstanceID);
    tags.add(nameTag);

    CreateTagsRequest ctr = new CreateTagsRequest(resources, tags);
    ec2.createTags(ctr);
    logger.info("Appended tag name name for the instance as " + nameTag);
}

public static void startInstance(List<String> instanceIds) {
    //start
    StartInstancesRequest startIR = new StartInstancesRequest(instanceIds);
    ec2.startInstances(startIR);
    logger.info("Instance successfully restarted.");
}

public static void stopInstance(List<String> instanceIds) {
    //stop
    StopInstancesRequest stopIR = new StopInstancesRequest(instanceIds);
    ec2.stopInstances(stopIR);
    logger.info("Instance successfully stopped.");
}

/**
 * Get a list of the current running instances. The key method is
 * DescribeInstancesResult describeInstancesResult =
 * ec2.describeInstances(); That returns information about instances that
 * you own. Note that gives you all the reservation that are currently
 * accounted in amazon. In other words an instance that has been stopped a
 * few minute ago is still consider "running instance for amazon". To refine
 * this list you need to use the method runningInst.getState().toString()
 * that tells you if the machine is really running or is terminated or
 * stopped or stopping or terminating or pending etc..
 *
 * @return Verbose description of the running instances.
 * @throws AmazonServiceException something wrong in Amazon
 * @throws Exception some communication failure
 */
public static String getRunningInstances() throws AmazonServiceException {
    logger.info("Fetching all running instances.");
    String ret = "";
    DescribeInstancesResult describeInstancesResult = ec2.describeInstances();

    // The list of reservations containing the describes instances.
    List<Reservation> reservations = describeInstancesResult.getReservations();
    Set<Instance> instances = new HashSet<>();

    for (Reservation reservation : reservations) {
        //Add the list of Amazon EC2 instances for this reservation.
        instances.addAll(reservation.getInstances());
    }

    ret += "You have " + instances.size() + " Amazon EC2 instance(s) running.\n";
    logger.info("You have " + instances.size() + " Amazon EC2 instance(s) running.");

    if (!instances.isEmpty()) {
        Iterator<Instance> instIterator = instances.iterator();
        int count = 0;
        //getting the descriptions of our running instances
        while (instIterator.hasNext()) {
            // the method runningInst.getState().toString() tell you if the machine is really running or is terminated or stopped or stopping or terminating or pending etc.. 
            Instance runningInst = instIterator.next();
            ret += "Instance: " + count + ", InstanceId: " + runningInst.getInstanceId() + ", ImageId: " + runningInst.getImageId() + ", type: " + runningInst.getInstanceType() + ", Started by: " + runningInst.getKeyName() + ", Status: " + runningInst.getState().toString() + "\n";
            logger.info("Instance: " + count + ", InstanceId: " + runningInst.getInstanceId() + ", ImageId: " + runningInst.getImageId() + ", type: " + runningInst.getInstanceType() + ", Started by: " + runningInst.getKeyName() + ", Status: " + runningInst.getState().toString());
            count++;
        }
    }

    return ret;

}

/**
 * Retrieve the list of zone that can be used for running the instances with
 * the user credential
 *
 * @return verbose string describing the zones
 * @throws AmazonServiceException something wrong in Amazon
 * @throws Exception some communication failure
 */
public static String listAvailableZones() throws AmazonServiceException {
    String ret = "";
    DescribeAvailabilityZonesResult availabilityZonesResult = ec2.describeAvailabilityZones();
    StringBuilder sb = new StringBuilder("You have access to " + availabilityZonesResult.getAvailabilityZones().size() + " Availability Zones.\n");
    ret += sb.toString();
    logger.info(sb.toString());

    List<AvailabilityZone> availabilityZone = availabilityZonesResult.getAvailabilityZones();
    Iterator<AvailabilityZone> iterator = availabilityZone.iterator();

    int i = 0;
    while (iterator.hasNext()) {
        AvailabilityZone az = iterator.next();
        ret += "Zone " + i + " " + az.getRegionName() + " " + az.getState() + " " + az.getZoneName() + "\n";
        logger.info("Zone " + i + " " + az.getRegionName() + " " + az.getState() + " " + az.getZoneName());
        i++;
    }
    return ret;

}

/**
 * Retrieve the list of possible Amazon Machine Image (AMI) that can be
 * instantiated by the user represented in the credential loaded during the
 * init() method. All the public AMI will be retrieved so the list will be
 * long. Many of the AMI will not have a description or a name but only an
 * ID so they will be useless. The AMI "ami-11ca2d78" is a sort of default
 * machine for amazon that all the user will be able to load
 *
 * @return Verbose description of the running instances.
 * @throws AmazonServiceException something wrong in Amazon
 */
public static String getAvailableImages() throws AmazonServiceException {
    String ret = "";
    DescribeImagesResult describeImagesResult = ec2.describeImages();
    logger.info("describe image result : " + describeImagesResult);
    List<Image> listOfImages = describeImagesResult.getImages();
    Iterator<Image> listOfImagesIterator = listOfImages.iterator();
    int count = 0;
    while (listOfImagesIterator.hasNext()) {
        Image img = listOfImagesIterator.next();

        StringBuilder sb = new StringBuilder("Image " + count + " Name: " + img.getName() + " Description: " + img.getDescription() + " Id: " + img.getImageId() + "\n");
        ret += sb.toString();
        logger.info(sb.toString());
        count++;
    }

    return ret;

}

/**
 * Create a key pair for a give user. The Keys are stored in yourHome/.ec2
 * or in the place that you specify while configuring the AWS plug-in for
 * java development. Note that you can always refer to this key pair using
 * just the name as long as the keys are correctly store in you machine.
 *
 * @param keyPairName unique name of the key pair
 * @return Object representing the Key pair
 * @throws AmazonServiceException something wrong in Amazon
 * @throws AmazonServiceException some communication failure
 */
public static KeyPair createKeyPair(String keyPairName) throws AmazonServiceException {
    // Create key pair for the given user.
    // request.getSecurityGroups().add("groupname");//create security groups
    // if you want create it! the security group will be default!
    // make sure to have access to SSH port 22 on the default group on the EC2console
    CreateKeyPairRequest kpReq = new CreateKeyPairRequest();
    kpReq.setKeyName(keyPairName);
    CreateKeyPairResult kpres = ec2.createKeyPair(kpReq);
    KeyPair keyPair = kpres.getKeyPair();
    logger.info("You havekeyPair.getKeyName = " + keyPair.getKeyName() + "\nkeyPair.getKeyFingerprint()=" + keyPair.getKeyFingerprint() + "\nkeyPair.getKeyMaterial()=" + keyPair.getKeyMaterial());
    return keyPair;
}

}

回答1:

You can use this (Refer the AWS Documentation) AWS userdata to run powershell commands to open ports in Windows Firewall and according to question I assume you are able to open the Security Group Rules.

Here are Powershell Command to Open port:

netsh advfirewall firewall add rule name="Open Port (your port number)" dir=in action=allow protocol=TCP localport=(your port number)

Hope it helps!