精华内容
下载资源
问答
  • 但是所有的Web项目想要共用同一个host和port(即同一个域名),而现网络上提供的云服务器大多数都是限制对外端口的,可用的端口一般只有80(http)、443(https)、22(SSH)、3389(Windows远程桌面),部分比较良心的...

    在开发Web项目的时候往往会遇到这种情况:后台服务端一个项目,前端客户端一个项目,微信平台对接一个项目,etc。但是所有的Web项目想要共用同一个host和port(即同一个域名),而现网络上提供的云服务器大多数都是限制对外端口的,可用的端口一般只有80(http)、443(https)、22(SSH)、3389(Windows远程桌面),部分比较良心的服务器可能还会提供8080(WWW代理服务)或者其他端口。如果所有项目都使用tomcat部署可以轻松解决这个问题,但是如果需要用到maven项目和tomcat项目复用端口,那就让人头痛了。

    我在接手别人的一个微信项目的时候就遇到这个问题,这个项目用SpringMVC实现,但是与微信平台对接却是使用Maven项目,而且交接的人没有跟我说用什么方式搭建服务器,最后就选择了我熟悉用的tomcat来部署SpringMVC的项目,但是这样问题就来了,Maven项目独占使用80端口,Tomcat项目使用8080端口在服务器上无法对外访问,而改为80端口又被Maven项目占用,这样只能选择开启443端口给Tomcat。

    我不甘心分配一个https的端口给一个本应该使用http端口的项目,因此我在网上找了一轮终于得知了Nginx反向代理的方法,经过一轮测试之后成功了,因此在这里记录下来。


    废话不多说直接上Nginx的安装和配置技巧

     1、安装gcc-c++

    [root@x ~]# yum -y install gcc-c++

    2、安装pcre

    PCRE 作用是让 Nginx 支持 Rewrite 功能。

    [root@x ~]# wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
    [root@x ~]# tar zxvf pcre-8.35.tar.gz
    [root@x ~]# cd pcre-8.35
    [root@x pcre-8.35]# ./configure
    [root@x pcre-8.35]# make && make install

    如果make install失败,可以尝试以下步骤

    [root@x pcre-8.35]# make clean
    [root@x pcre-8.35]# make install

    检查版本号,8.35为正确版本,安装pcre成功

    [root@x pcre-8.35]# pcre-config --version
    8.35

    3、安装Nginx

    [root@x pcre-8.35]# cd ~
    [root@x ~]# tar zxvf nginx-1.6.2.tar.gz
    [root@x ~]# cd nginx-1.6.2
    [root@x nginx-1.6.2]# ./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/root/pcre-8.35
    [root@x nginx-1.6.2]# make
    [root@x nginx-1.6.2]# make install
    

    查看版本号

    [root@x nginx-1.6.2]# /usr/local/webserver/nginx/sbin/nginx -v
    nginx version: nginx/1.6.2

    这样就安装完成了。

    4、理解Nginx配置

    安装完成后,/usr/local/webserver/nginx/就是nginx的目录,在该目录下的conf目录有一个nginx.conf文件,这个就是nginx的配置文件,我们现在查看一下

    [root@x nginx-1.6.2]# cd /usr/local/webserver/nginx/conf
    [root@x conf]# vim nginx.conf
    
    http{
        ...
        server{
            listen        80;        #监听端口
            server_name   localhost; #监听主机
    
            location {               #路径过滤
                root        html;    #目录
                index       index.html index.htm;    #主页选择
            }
            ...
            location /50x.html {
                root        html;
            }
        }
    }

    这是Nginx的配置,当访问http://%server_name%:%listen%时,Nginx会进行路径过滤,符合路径所以返回index.html,当访问http://%server_name%:%listen%/50x.html时,会返回在html目录下的50x.html。

    可能这样看还不是很懂,但是不用管,能使用就行了,接下来我们只需要知道两个东西,一个是proxy_pass的用法,一个是location的替换方式。

    http{
        upstream server8080{        #server group
            server localhost:8080;  #server8080对应的server
        }
        upstream server8081{
            server localhost:8081;
        }
        ...
        server{
            listen        80;
            server_name   localhost;
            ...
            location /addr1/{
                proxy_pass    http://server8080/addr1/;
            }
            location /addr2/{
                proxy_pass    http://localhost:8081/addr2/;
            }
            location /addr[0-9]*/{
                proxy_pass    http://server8081/addr2/;
            }
        }
    }

    在上面这个例子中,upstream是映射一组server group,即是:访问http://server8080/相当于访问http://localhost:8080/。因此不多介绍。而关键在于proxy_pass,这是Nginx反向代理的一个重要变量,在上述例子中,例如访问http://localhost:80/addr1/test.html,Nginx会让服务端变为去访问http://localhost:8080/addr1/test.html,因为Nginx监听到localhost端口80有访问,于是在location里寻找符合正则的项,/addr1/,然后将访问网址变为proxy_pass的网址。

    同样第三个location表示在访问http://localhost:80/addr*/,*为0-9时,都相当于访问http://localhost:8081/addr2/。因此要做的事情就很明朗了,只需要修改Nginx配置文件,加入新的location规则,让其反向代理到不同的端口,就可以实现多个项目共享80端口了

    这种方法本质上不是共用,只是反向代理,tomcat占据的端口依然是8080,maven项目占据的端口依然是8081,只是本来访问服务器的8080端口和8081端口是无法访问的,而现在能通过访问80端口反向代理到不同的端口上,实现方式和共用类似,可以解决只有一个访问入口而多个web项目使用冲突的问题。

    最后为了Nginx使用方便,提供一个shell脚本

    #nginx.sh
    NGINX=/usr/local/webserver/nginx/sbin/nginx
    start(){
    	$NGINX
    }
    stop(){
    	$NGINX -s stop
    }
    restart(){
    	$NGINX -s reopen
    }
    reload(){
    	$NGINX -s reload
    }
    
    case $1 in
    	-start)
    	start
    	;;
    	-stop)
    	stop
    	;;
    	-restart)
    	restart
    	;;
    	-reload)
    	reload
    	;;
    	*)
    	$NGINX $1
    	;;
    esac
    exit 1
    #启动 sh nginx.sh -start
    #停止 sh nginx.sh -stop
    #重启 sh nginx.sh -restart
    #重新加载配置 sh nginx.sh -reload
    #接收指令 sh nginx.sh $instruct

    Nginx其他还有很多有用的功能,想要搭建大型服务器是个很好的选择,更详细的内容可以自己在网络上发掘。

    dadi

    2018/9/19

    展开全文
  • 通过只启用需要用到的服务、关闭暂时用不到的服务或不用的服务,这样最大程度来提高安全性。 作为web服务器,并不是所有默认服务都需要的,所以像打印、共享服务都可以禁用。当然了,你的系统补丁也需要更新到最新,...
  • 使用纯Java实现一个WebSSH项目

    万次阅读 多人点赞 2020-03-10 13:18:21
    使用纯Java语言实现的WebSSH项目。 技术:SpringBoot+WebSockey+jsch+xterm.js

    前言

    最近由于项目需求,项目中需要实现一个WebSSH连接终端的功能,由于自己第一次做这类型功能,所以首先上了GitHub找了找有没有现成的轮子可以拿来直接用,当时看到了很多这方面的项目,例如:GateOne、webssh、shellinabox等,这些项目都可以很好地实现webssh的功能,但是最终并没有采用,原因是在于这些底层大都是python写的,需要依赖很多文件,自己用的时候可以使用这种方案,快捷省事,但是做到项目中供用户使用时,总不能要求用户做到服务器中必须包含这些底层依赖,这显然不太合理,所以我决定自己动手写一个WebSSH的功能,并且作为一个独立的项目开源出来。

    github项目开源地址:https://github.com/NoCortY/WebSSH

    技术选型

    由于webssh需要实时数据交互,所以会选用长连接的WebSocket,为了开发的方便,框架选用SpringBoot,另外还自己了解了Java用户连接ssh的jsch和实现前端shell页面的xterm.js.

    所以,最终的技术选型就是 SpringBoot+Websocket+jsch+xterm.js

    导入依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <!-- Web相关 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- jsch支持 -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>
        <!-- WebSocket 支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <!-- 文件上传解析器 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
    </dependencies>
    

    一个简单的xterm案例

    由于xterm是一个冷门技术,所以很多同学并没有这方面的知识支撑,我也是为了实现这个功能所以临时学的,所以在这给大家介绍一下。

    xterm.js是一个基于WebSocket的容器,它可以帮助我们在前端实现命令行的样式。就像是我们平常再用SecureCRT或者XShell连接服务器时一样。

    下面是官网上的入门案例:

    <!doctype html>
     <html>
      <head>
        <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
        <script src="node_modules/xterm/lib/xterm.js"></script>
      </head>
      <body>
        <div id="terminal"></div>
        <script>
          var term = new Terminal();
          term.open(document.getElementById('terminal'));
          term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
        </script>
      </body>
     </html>
    

    最终测试,页面就是下面这个样子:

    xterm入门

    可以看到页面已经出现了类似与shell的样式,那就根据这个继续深入,实现一个webssh。

    后端实现

    由于xterm只要只是实现了前端的样式,并不能真正地实现与服务器交互,与服务器交互主要还是靠我们Java后端来进行控制的,所以我们从后端开始,使用jsch+websocket实现这部分内容。

    • WebSocket配置

      由于消息实时推送到前端需要用到WebSocket,不了解WebSocket的同学可以先去自行了解一下,这里就不过多介绍了,我们直接开始进行WebSocket的配置。

      /**
      * @Description: websocket配置
      * @Author: NoCortY
      * @Date: 2020/3/8
      */
      @Configuration
      @EnableWebSocket
      public class WebSSHWebSocketConfig implements WebSocketConfigurer{
          @Autowired
          WebSSHWebSocketHandler webSSHWebSocketHandler;
          @Override
          public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
              //socket通道
              //指定处理器和路径,并设置跨域
              webSocketHandlerRegistry.addHandler(webSSHWebSocketHandler, "/webssh")
                      .addInterceptors(new WebSocketInterceptor())
                      .setAllowedOrigins("*");
          }
      }
      
    • 处理器(Handler)和拦截器(Interceptor)的实现

      刚才我们完成了WebSocket的配置,并指定了一个处理器和拦截器。所以接下来就是处理器和拦截器的实现。

      拦截器

      public class WebSocketInterceptor implements HandshakeInterceptor {
          /**
           * @Description: Handler处理前调用
           * @Param: [serverHttpRequest, serverHttpResponse, webSocketHandler, map]
           * @return: boolean
           * @Author: NoCortY
           * @Date: 2020/3/1
           */
          @Override
          public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
              if (serverHttpRequest instanceof ServletServerHttpRequest) {
                  ServletServerHttpRequest request = (ServletServerHttpRequest) serverHttpRequest;
                  //生成一个UUID,这里由于是独立的项目,没有用户模块,所以可以用随机的UUID
                  //但是如果要集成到自己的项目中,需要将其改为自己识别用户的标识
                  String uuid = UUID.randomUUID().toString().replace("-","");
                  //将uuid放到websocketsession中
                  map.put(ConstantPool.USER_UUID_KEY, uuid);
                  return true;
              } else {
                  return false;
              }
          }
      
          @Override
          public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
      
          }
      }
      

      处理器

      /**
      * @Description: WebSSH的WebSocket处理器
      * @Author: NoCortY
      * @Date: 2020/3/8
      */
      @Component
      public class WebSSHWebSocketHandler implements WebSocketHandler{
          @Autowired
          private WebSSHService webSSHService;
          private Logger logger = LoggerFactory.getLogger(WebSSHWebSocketHandler.class);
      
          /**
           * @Description: 用户连接上WebSocket的回调
           * @Param: [webSocketSession]
           * @return: void
           * @Author: Object
           * @Date: 2020/3/8
           */
          @Override
          public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
              logger.info("用户:{},连接WebSSH", webSocketSession.getAttributes().get(ConstantPool.USER_UUID_KEY));
              //调用初始化连接
              webSSHService.initConnection(webSocketSession);
          }
      
          /**
           * @Description: 收到消息的回调
           * @Param: [webSocketSession, webSocketMessage]
           * @return: void
           * @Author: NoCortY
           * @Date: 2020/3/8
           */
          @Override
          public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
              if (webSocketMessage instanceof TextMessage) {
                  logger.info("用户:{},发送命令:{}", webSocketSession.getAttributes().get(ConstantPool.USER_UUID_KEY), webSocketMessage.toString());
                  //调用service接收消息
                  webSSHService.recvHandle(((TextMessage) webSocketMessage).getPayload(), webSocketSession);
              } else if (webSocketMessage instanceof BinaryMessage) {
      
              } else if (webSocketMessage instanceof PongMessage) {
      
              } else {
                  System.out.println("Unexpected WebSocket message type: " + webSocketMessage);
              }
          }
      
          /**
           * @Description: 出现错误的回调
           * @Param: [webSocketSession, throwable]
           * @return: void
           * @Author: Object
           * @Date: 2020/3/8
           */
          @Override
          public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
              logger.error("数据传输错误");
          }
      
          /**
           * @Description: 连接关闭的回调
           * @Param: [webSocketSession, closeStatus]
           * @return: void
           * @Author: NoCortY
           * @Date: 2020/3/8
           */
          @Override
          public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
              logger.info("用户:{}断开webssh连接", String.valueOf(webSocketSession.getAttributes().get(ConstantPool.USER_UUID_KEY)));
              //调用service关闭连接
              webSSHService.close(webSocketSession);
          }
      
          @Override
          public boolean supportsPartialMessages() {
              return false;
          }
      }
      

      需要注意的是,我在拦截器中加入的用户标识是使用了随机的UUID,这是因为作为一个独立的websocket项目,没有用户模块,如果需要将这个项目集成到自己的项目中,需要修改这部分代码,将其改为自己项目中识别一个用户所用的用户标识。

    • WebSSH的业务逻辑实现(核心)

      刚才我们实现了websocket的配置,都是一些死代码,实现了接口再根据自身需求即可实现,现在我们将进行后端主要业务逻辑的实现,在实现这个逻辑之前,我们先来想想,WebSSH,我们主要想要呈现一个什么效果。

      我这里做了一个总结:

      1.首先我们得先连接上终端(初始化连接)

      2.其次我们的服务端需要处理来自前端的消息(接收并处理前端消息)

      3.我们需要将终端返回的消息回写到前端(数据回写前端)

      4.关闭连接

      根据这四个需求,我们先定义一个接口,这样可以让需求明了起来。

      /**
       * @Description: WebSSH的业务逻辑
       * @Author: NoCortY
       * @Date: 2020/3/7
       */
      public interface WebSSHService {
          /**
           * @Description: 初始化ssh连接
           * @Param:
           * @return:
           * @Author: NoCortY
           * @Date: 2020/3/7
           */
          public void initConnection(WebSocketSession session);
      
          /**
           * @Description: 处理客户段发的数据
           * @Param:
           * @return:
           * @Author: NoCortY
           * @Date: 2020/3/7
           */
          public void recvHandle(String buffer, WebSocketSession session);
      
          /**
           * @Description: 数据写回前端 for websocket
           * @Param:
           * @return:
           * @Author: NoCortY
           * @Date: 2020/3/7
           */
          public void sendMessage(WebSocketSession session, byte[] buffer) throws IOException;
      
          /**
           * @Description: 关闭连接
           * @Param:
           * @return:
           * @Author: NoCortY
           * @Date: 2020/3/7
           */
          public void close(WebSocketSession session);
      }
      

      现在我们可以根据这个接口去实现我们定义的功能了。

      1. 初始化连接

        由于我们的底层是依赖jsch实现的,所以这里是需要使用jsch去建立连接的。而所谓初始化连接,实际上就是将我们所需要的连接信息,保存在一个Map中,这里并不进行任何的真实连接操作。为什么这里不直接进行连接?因为这里前端只是连接上了WebSocket,但是我们还需要前端给我们发来linux终端的用户名和密码,没有这些信息,我们是无法进行连接的。

        public void initConnection(WebSocketSession session) {
                JSch jSch = new JSch();
                SSHConnectInfo sshConnectInfo = new SSHConnectInfo();
                sshConnectInfo.setjSch(jSch);
                sshConnectInfo.setWebSocketSession(session);
                String uuid = String.valueOf(session.getAttributes().get(ConstantPool.USER_UUID_KEY));
                //将这个ssh连接信息放入map中
                sshMap.put(uuid, sshConnectInfo);
        }
        
      2. 处理客户端发送的数据

        在这一步骤中,我们会分为两个分支。

        第一个分支:如果客户端发来的是终端的用户名和密码等信息,那么我们进行终端的连接。

        第二个分支:如果客户端发来的是操作终端的命令,那么我们就直接转发到终端并且获取终端的执行结果。

        具体代码实现:

        public void recvHandle(String buffer, WebSocketSession session) {
                ObjectMapper objectMapper = new ObjectMapper();
                WebSSHData webSSHData = null;
                try {
                    //转换前端发送的JSON
                    webSSHData = objectMapper.readValue(buffer, WebSSHData.class);
                } catch (IOException e) {
                    logger.error("Json转换异常");
                    logger.error("异常信息:{}", e.getMessage());
                    return;
                }
            //获取刚才设置的随机的uuid
                String userId = String.valueOf(session.getAttributes().get(ConstantPool.USER_UUID_KEY));
                if (ConstantPool.WEBSSH_OPERATE_CONNECT.equals(webSSHData.getOperate())) {
                    //如果是连接请求
                    //找到刚才存储的ssh连接对象
                    SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
                    //启动线程异步处理
                    WebSSHData finalWebSSHData = webSSHData;
                    executorService.execute(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //连接到终端
                                connectToSSH(sshConnectInfo, finalWebSSHData, session);
                            } catch (JSchException | IOException e) {
                                logger.error("webssh连接异常");
                                logger.error("异常信息:{}", e.getMessage());
                                close(session);
                            }
                        }
                    });
                } else if (ConstantPool.WEBSSH_OPERATE_COMMAND.equals(webSSHData.getOperate())) {
                    //如果是发送命令的请求
                    String command = webSSHData.getCommand();
                    SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
                    if (sshConnectInfo != null) {
                        try {
                            //发送命令到终端
                            transToSSH(sshConnectInfo.getChannel(), command);
                        } catch (IOException e) {
                            logger.error("webssh连接异常");
                            logger.error("异常信息:{}", e.getMessage());
                            close(session);
                        }
                    }
                } else {
                    logger.error("不支持的操作");
                    close(session);
                }
        }
        
      3. 数据通过websocket发送到前端

        public void sendMessage(WebSocketSession session, byte[] buffer) throws IOException {
                session.sendMessage(new TextMessage(buffer));
        }
        
      4. 关闭连接

        public void close(WebSocketSession session) {
            //获取随机生成的uuid
                String userId = String.valueOf(session.getAttributes().get(ConstantPool.USER_UUID_KEY));
                SSHConnectInfo sshConnectInfo = (SSHConnectInfo) sshMap.get(userId);
                if (sshConnectInfo != null) {
                    //断开连接
                    if (sshConnectInfo.getChannel() != null) sshConnectInfo.getChannel().disconnect();
                    //map中移除该ssh连接信息
                    sshMap.remove(userId);
                }
        }
        

      至此,我们的整个后端实现就结束了,由于篇幅有限,这里将一些操作封装成了方法,就不做过多展示了,重点讲逻辑实现的思路吧。接下来我们将进行前端的实现。

    前端实现

    前端工作主要分为这么几个步骤:

    1. 页面的实现
    2. 连接WebSocket并完成数据的接收并回写
    3. 数据的发送

    所以我们一步一步来实现它。

    • 页面实现

      页面的实现很简单,我们只不过需要在一整个屏幕上都显示终端那种大黑屏幕,所以我们并不用写什么样式,只需要创建一个div,之后将terminal实例通过xterm放到这个div中,就可以实现了。

      <!doctype html>
      <html>
      <head>
          <title>WebSSH</title>
          <link rel="stylesheet" href="../css/xterm.css" />
      </head>
      <body>
      <div id="terminal" style="width: 100%;height: 100%"></div>
      
      <script src="../lib/jquery-3.4.1/jquery-3.4.1.min.js"></script>
      <script src="../js/xterm.js" charset="utf-8"></script>
      <script src="../js/webssh.js" charset="utf-8"></script>
      <script src="../js/base64.js" charset="utf-8"></script>
      </body>
      </html>
      
    • 连接WebSocket并完成数据的发送、接收、回写

      openTerminal( {
          //这里的内容可以写死,但是要整合到项目中时,需要通过参数的方式传入,可以动态连接某个终端。
              operate:'connect',
              host: 'ip地址',
              port: '端口号',
              username: '用户名',
              password: '密码'
          });
          function openTerminal(options){
              var client = new WSSHClient();
              var term = new Terminal({
                  cols: 97,
                  rows: 37,
                  cursorBlink: true, // 光标闪烁
                  cursorStyle: "block", // 光标样式  null | 'block' | 'underline' | 'bar'
                  scrollback: 800, //回滚
                  tabStopWidth: 8, //制表宽度
                  screenKeys: true
              });
      
              term.on('data', function (data) {
                  //键盘输入时的回调函数
                  client.sendClientData(data);
              });
              term.open(document.getElementById('terminal'));
              //在页面上显示连接中...
              term.write('Connecting...');
              //执行连接操作
              client.connect({
                  onError: function (error) {
                      //连接失败回调
                      term.write('Error: ' + error + '\r\n');
                  },
                  onConnect: function () {
                      //连接成功回调
                      client.sendInitData(options);
                  },
                  onClose: function () {
                      //连接关闭回调
                      term.write("\rconnection closed");
                  },
                  onData: function (data) {
                      //收到数据时回调
                      term.write(data);
                  }
              });
          }
      

    效果展示

    • 连接

      连接

    • 连接成功

      连接成功

    • 命令操作

      ls命令:

      ls命令

      vim编辑器:

      vim编辑器

      top命令:

      top命令

    结语

    这样我们就完成了一个webssh项目的实现,没有依赖其它任何的组件,后端完全使用Java实现,由于用了SpringBoot,非常容易部署。

    但是,我们还可以对这个项目进行扩展,比如新增上传或下载文件,就像Xftp一样,可以很方便地拖拽式上传下载文件。

    这个项目之后我会持续更新,上述功能也会慢慢实现,Github:https://github.com/NoCortY/WebSSH

    喜欢可以给个Star哦~

    欢迎大家访问我的个人博客:Object’s Blog

    展开全文
  • 在搭建服务器的时候,项目部署在tomcat上,要访问项目,则需要加上端口号,如何隐藏端口号来访问呢,这就用到了nginx. nginx可以在docker上安装,也可以在linux上安装,这里我建议使用linux,因为修改配置文件需要...

    在搭建服务器的时候,项目部署在tomcat上,要访问项目,则需要加上端口号,如何隐藏端口号来访问呢,这就用到了nginx.

    nginx可以在docker上安装,也可以在linux上安装,这里我建议使用linux,因为修改配置文件需要使用vim,而docker容器是默认不带vim的,而且下载极慢。nginx作为最后一道关口,在个人服务器上,网速慢的情况下,我建议直接安装在linux上。

    在linux安装nginx极其简单–>

    $ sudo apt update
    $ sudo apt install nginx
    

    下面的内容docker上可以同样操作。

    而实现代理功能呢,就要配置一下了
    首先呢,是要关闭防火墙,打开80端口

    sudo ufw disable 关闭防火墙
    sudo ufw allow 80 允许外部访问80端口(tcp/udp)

    接着就是配置代理端口了,进入nginx的目录下cd /etc/nginx/
    vi nginx.conf(这里建议进行一下备份,以防你改坏咯)
    然后把下面的格式复制到你的
    http{
            放这里
    }

    server {
    			#这里就是你的nginx的端口和你外面的域名
                listen 80;
                server_name www.nihaoya.com;
    			
    			#这里的 /test1 的意思就是你的域名加上/test1 就访问里面的那个路径/项目了
                location /test1 {
                        proxy_pass http://www.baidu.com;
                }
    
                location /test2 {
                        proxy_pass http://www.163.com;
                }
    
    			#这里就是不加东西访问的路径
                location / {
                       proxy_pass http://hahhah.com;
                }
    
    			# 举一个我正在使用的例子
    			# 外面访问的时候使用www.nihaoya.com/about
    			# 访问的资源是服务器内的 :10011/about
    			location /about {
                    proxy_pass http://127.0.0.1:10011/about;
            	}
        }
    

    然后:wq退出,测试、重启nginx

    sudo nginx -t
    sudo nginx -s reload
    

    如果这里测试出现了什么问题,可能是你哪里弄错了,也可能是防火墙问题。

    然后 你就可以通过你上面文件里面的配置去访问你的网站了。
    以上 !

    展开全文
  • Web页面请求过程所用到的协议

    千次阅读 2021-08-06 16:21:04
    Web页面请求过程可能会用到的协议:DHCP(UDP)、DNS(UDP)、HTTP(TCP);ARP、OSPF、RIP、BGP 工作流程: 首先若主机无IP信息,则需要DHCP配置主机信息(IP、子网掩码、默认网关IP、DNS服务器IP),全是广播报文...
    • Web页面请求过程可能会用到的协议:DHCP(UDP)、DNS(UDP)、HTTP(TCP);ARP、OSPF、RIP、BGP
    • 工作流程

       首先若主机无IP信息,则需要DHCP配置主机信息(IP、子网掩码、默认网关IP、DNS服务器IP),全是广播报文(FF:FF:FF:FF:FF:FF),并且四次信息交换后才确定好本机IP等信息。它利用UDP报文在客户端68和服务器端67之间传递报文。

       然后通过DNS来解析网站域名对应的IP地址(HTTP服务器),通过网关路由器来与DNS服务器交换信息通过递归/迭代查询得到此信息。它利用UDP在53号端口来传递报文。

       最后则是要与提供所需服务的HTTP服务器建立起TCP连接,生成TCP套接字从而请求接收服务。先是TCP三次握手(客TCP SYN、服TCP SYN ACK、客TCP ACK-捎带HTTP GET报文请求服务),然后HTTP服务器根据HTTP GET报文生成一个响应,将请求的Web页面内容放入报文主体中发回给主机。客户端收到后则会抽取出页面内容,然后进行渲染,显示Web页面。

       在这个数据包传输过程中,若存在无ARP缓存的情况,则首先需要ARP协议来完成IP地址到MAC地址的寻址过程(才可完成点到点的传输,局域网内广播帧)。同时路由器的转发表则涉及到OSPF、RIP(内部网关协议)和BGP(外部网关协议)等路由选择协议来进行相关配置。

    展开全文
  • Java开发中常用数据库默认端口oracle 1521 、mysql 3306、sqlserver 1433等,及网络常用端口
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    文件为doc版,可自行转成txt,在手机上看挺好的。 本资源来自网络,如有纰漏还请告知,如觉得还不错,请留言告知后来人,谢谢!!!!! ...入门学习Linux常用必会60个命令实例详解 ...Linux提供了大量的命令,利用它...
  • IntelliJ IDEA导入Web项目

    万次阅读 多人点赞 2018-03-13 10:47:21
    转自:Idea导入Web项目 概述 主要分为项目配置和tomcat配置两大步骤。 一、项目配置 打开idea,选择导入项目 选择将要打开的项目路径后,继续选择项目的原本类型(后续引导设置会根据原本的...
  • 需要的结果:需要同时用到https的443端口,并且访问http时,自动跳到https中去 思路: [1]代理web项目很简单,按照之前的操作即可。 [2]代理vue项目时,为了和web项目的路径区分,在vue项目中添加前缀 路由配置...
  • Network 【常用协议端口号】

    千次阅读 2017-06-07 16:30:17
    常用网络协议端口号汇总。
  • 这篇文章主要介绍了Win2008 R2 WEB 服务器安全设置指南之禁用不必要的服务和关闭端口,需要的朋友可以参考下  安全是重中之重,以最少的服务换取最大的安全。通过只启用需要用到的服务、关闭暂时用不到的服务或不用...
  • 8020:前端页面的端口吗? 18080:历史服务器的端口 8088:yarn的端口 8080:spark集群的master端口 7077:spark提交的时候的端口号spark-...8081:spark worker的webui端口 8080:sparkmaster 7077:sparkmas...
  • IT开发+软件测试常用端口

    千次阅读 2019-07-04 21:55:04
    **端口号**具有网络功能的应用软件的标识号。注意,端口号是不固定的,即可以由用户手工可以分配(当然,一般在软件编写时就已经定义) 0-1023是公认端口号,即已经公认定义或为将要公认定义的软件保留的,而1024-...
  • 不是访问浏览器80端口,而是浏览器访问web服务器的80端口。 80端口是http协议规定的标准默认端口,指的是服务器监听80端口,而不是客户端必须使用80端口。 浏览器发送给web服务器的数据包,源端口当然可以不是80端口...
  • 8082的端口用于其他项目了,但是mycat-eye监测工具也要用到8082端口,但是不知道在哪里修改,有大神解答吗?
  • tomcat中用到端口的各自功能

    千次阅读 2016-09-09 14:33:49
    3>reloadable如果这个属性设为true, Tomcat服务器在运行状态下会监视在WEB-INF/classes和Web-INF/lib目录CLASS文件的改运.如果监视到有class文件被更新,服务器自重新加载Web应用 3>cookies指定是否通过Cookies来支持...
  • Web 服务需要配置监听的 IP 和端口才可以对外提供真正的服务。本文介绍如何设置 ASP.NET Core 程序监听的 IP 和端口。 ASP.NET Core 程序默认集成了 Kestrel 服务器,可以直接对外提供 Web 服务。虽然可以直接提供...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...
  • Linux常用与不常用端口一览表

    千次阅读 2020-10-24 16:08:18
    常用端口号: IIS(HTTP):80 SQLServer:1433 Oracle:1521 MySQL:3306 FTP:21 SSH:22 Tomcat:8080 Telnet :23 常用和不常用端口一览表 端口:0 服务:Reserved 说明:通常用于分析操作系统。这一方法能够...
  • Hadoop2.x各个端口

    千次阅读 2016-11-25 11:19:38
    Hadoop各个端口详解的查看链接 1.DataNode的http服务的端口、ipc服务的端口分别是哪个? 2.NameNode的http服务的端口、ipc服务的端口分别是哪个? 3.journalnode的http服务的端口、ipc服务的端口分别是哪个? 4...
  • Flask框架的一大特色就是简单,简单得令人发指。只需要很少的代码,就可以编写一个可以运行的Web应用。下面就看一下使用Flask框架开发Web应用的基本步骤。1.导入f...
  • 80 vCenter Server需要端口80用于直接HTTP连接。...389 此端口在vCenter Server的本地和所有远程实例上必须处于打开状态。这是vCenter Server组的目录服务的LDAP端口号。vCenter Server系统需要绑定...
  • tomcat端口号作用及区别详解

    千次阅读 2020-05-09 09:51:56
    从tomcat配置文件中,我们可以看出,在启动tomcat的时候默认启动了3个端口,分别是8080(8443)、8009、8005。 一.8080(8443)端口 <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" ...
  • PC所有端口简介

    千次阅读 2019-05-14 15:29:13
    所有端口简介 端口 描述 状态 0/TCP,UDP 保留端口;不使用(若发送过程不准备接受回复消息,则可以作为源端口) 官方 1/TCP,UDP TCPMUX(传输控制协议端口服务多路开关选择器) 官方 5/TCP,UDP RJE(远程作业登录) ...
  • Arthas Web Console

    千次阅读 2019-08-21 11:03:18
    环境 Arthas 3.1.1 Centos7 ...只介绍咱们接下来能用到的命令 java -jar arthas-boot.jar 指定要attach的java进程id(一般不用指定,启动之后可以再做选择) java -jar arthas-boot.jar --target-i...
  • PHPSTUDY端口被占用解决方法

    千次阅读 2020-08-23 15:20:49
    打开phpstudy竟然发现端口被占用 用win+r,输入cmd 输入命令 netstat -ano查找端口对应的pid 打开任务管理器 发现占用80端口的竟然是system
  • Linux下WEB 测试工具

    2014-11-03 09:35:00
    比较使用的web服务器扫描工具,可以用于漏洞扫描或web站点维护
  • Hadoop各个服务端口列表

    万次阅读 2018-01-10 17:12:36
    端口 Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问。而随着Hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如此,以便查询。...
  • Linux常见的端口

    2020-11-03 11:31:26
    ftp 20(数据端口) 21(控制端口) ssh 22 telnet 23 DNS 53 http(web端) 80 https 443 tomcat 8080访问web端口,8005 t omcat本身自己的端口,8009 与http等服务器建立连接的端口
  • 软件常见端口

    千次阅读 2019-04-23 16:22:09
    著名端口 端口号码 / 层 名称 注释 1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 111,291
精华内容 44,516
关键字:

web用到的端口