Document how to create a Callhome Server #146

Open
opened 2026-06-02 11:38:20 +00:00 by dazhuang6 · 5 comments
dazhuang6 commented 2026-06-02 11:38:20 +00:00 (Migrated from github.com)

May I ask when NetConf Call Home will be supported?

May I ask when NetConf Call Home will be supported?
nemith commented 2026-06-02 16:15:04 +00:00 (Migrated from github.com)

Can you please talk more about exactly what you would be looking for from call home. Really it's supported now. Evertime I have gone to create some sort of actual "call home" feature. It comes back down to just having a network socket that listens for connections and then creates a new session on top of that connection.

The only real thing is it needs to be documented.

However It would be good to know your exact requirements?

Can you please talk more about exactly what you would be looking for from call home. Really it's supported now. Evertime I have gone to create some sort of actual "call home" feature. It comes back down to just having a network socket that listens for connections and then creates a new session on top of that connection. The only real thing is it needs to be documented. However It would be good to know your exact requirements?
dazhuang6 commented 2026-06-02 16:44:04 +00:00 (Migrated from github.com)

I have a requirement: the netconf server on the device is located in different campuses, and at this time, the netconf client cannot directly communicate with the device, so the netconf call home function needs to be used.

As you mentioned, it listens for TCP connections and then establishes SSH and Netconf sessions based on this connection.

Could you please submit that part of the code? That would be very helpful. Thank you.

I have a requirement: the netconf server on the device is located in different campuses, and at this time, the netconf client cannot directly communicate with the device, so the netconf call home function needs to be used. As you mentioned, it listens for TCP connections and then establishes SSH and Netconf sessions based on this connection. Could you please submit that part of the code? That would be very helpful. Thank you.
nemith commented 2026-06-02 21:30:14 +00:00 (Migrated from github.com)

I am more curious on what you would do across the sessions? Is this for notificaitons or for issuing RPCs over them? If it's RPCs how would you index them? How would you do auth? (see how each one of these makes it harder to havea generic handler).

Here is a rough way to do it. I haven't added this to the library as the abstraction is already good and eveything else would be added noise to it.

Something like

func startCallHome() {
	listener, err := net.Listen("tcp", ":4334")
	if err != nil {
		log.Fatalf("Failed to bind to port: %v", err)
	}
	defer listener.Close() // Ensure resource cleanup

	fmt.Println("Call home server listening on 4334...")

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("Failed to accept connection: %v", err)
			continue
		}

		go handleConnection(conn)
	}
}

func handleConnection(conn *net.Conn) {
  // you may need to customize this config on a per connection basis.  
   config := &ssh.ClientConfig{
		User: "username",
		Auth: []ssh.AuthMethod{
			ssh.Password("password"),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(), // just for example purposes, you probably want to validate this for security purposes 
		Timeout:         10 * time.Second,
	}

	// Perform the SSH handshake over the existing net.Conn.
	c, chans, reqs, err := ssh.NewClientConn(conn, conn.RemoteAddr().String(), config)
	if err != nil {
		return nil, err
	}

   client := ssh.NewClient(c, chans, reqs)

   tr, err := ncssh.NewTransport(client)
   if err != nil {
      log.Printf("failed to create netconf transport: %v", err)
   } 

   session, err := netconf.NewSession(tr) 
   if err != nil {
      log.Printf("failed to create netconf session: %v", err)
   }

  // Do something with the session?  Put it in a map based on the hostname?   Just issue commands?  Do you need to send some sort of keepalive?  This will all be dependent on what you needs are.  
}

i'd probably take your requirements and wrap that into a struct to hold a map of sessions (assuming that is how you are going to use it) and make the startCallHome() and handleConnection() methods off of that struct.

But each step here could require some sort of customization and just making this a bunch of call back feels wrong and I don't thinks it's necessary as a core part of this library at this point, but I am open to feedback.

I am more curious on what you would do across the sessions? Is this for notificaitons or for issuing RPCs over them? If it's RPCs how would you index them? How would you do auth? (see how each one of these makes it harder to havea generic handler). Here is a rough way to do it. I haven't added this to the library as the abstraction is already good and eveything else would be added noise to it. Something like ```go func startCallHome() { listener, err := net.Listen("tcp", ":4334") if err != nil { log.Fatalf("Failed to bind to port: %v", err) } defer listener.Close() // Ensure resource cleanup fmt.Println("Call home server listening on 4334...") for { conn, err := listener.Accept() if err != nil { log.Printf("Failed to accept connection: %v", err) continue } go handleConnection(conn) } } func handleConnection(conn *net.Conn) { // you may need to customize this config on a per connection basis. config := &ssh.ClientConfig{ User: "username", Auth: []ssh.AuthMethod{ ssh.Password("password"), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // just for example purposes, you probably want to validate this for security purposes Timeout: 10 * time.Second, } // Perform the SSH handshake over the existing net.Conn. c, chans, reqs, err := ssh.NewClientConn(conn, conn.RemoteAddr().String(), config) if err != nil { return nil, err } client := ssh.NewClient(c, chans, reqs) tr, err := ncssh.NewTransport(client) if err != nil { log.Printf("failed to create netconf transport: %v", err) } session, err := netconf.NewSession(tr) if err != nil { log.Printf("failed to create netconf session: %v", err) } // Do something with the session? Put it in a map based on the hostname? Just issue commands? Do you need to send some sort of keepalive? This will all be dependent on what you needs are. } ``` i'd probably take your requirements and wrap that into a struct to hold a map of sessions (assuming that is how you are going to use it) and make the startCallHome() and handleConnection() methods off of that struct. But each step here could require some sort of customization and just making this a bunch of call back _feels_ wrong and I don't thinks it's necessary as a core part of this library at this point, but I am open to feedback.
nemith commented 2026-06-03 15:27:10 +00:00 (Migrated from github.com)

Let me know if this doesn't work or if you have some other questions. The real meat & potatoes here is what to do with the sessions? Do you hold onto them? Do you track them? Do you use them only for push notifications, etc.

Given how wide that all is I still looking at this and I don't think the netconf library can abstract this any better (but perhaps maybe a helper func or two?)

Let me know if this doesn't work or if you have some other questions. The real meat & potatoes here is what to do with the sessions? Do you hold onto them? Do you track them? Do you use them only for push notifications, etc. Given how wide that all is I still looking at this and I don't think the netconf library can abstract this any better (but perhaps maybe a helper func or two?)
dazhuang6 commented 2026-06-03 16:07:53 +00:00 (Migrated from github.com)

The problem I'm currently facing is how to handle device authentication, which is related to my specific business.

For sessions established via call home, my requirement is to retain this session indefinitely and rely on it for all RPC requests.

The problem I'm currently facing is how to handle device authentication, which is related to my specific business. For sessions established via call home, my requirement is to retain this session indefinitely and rely on it for all RPC requests.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nemith/netconf#146
No description provided.