Elixir Xmpp Ejabberd ejabberd_c2s.open_session function arguments? - xmpp

I am trying open a new session in ejabberd xmpp server by the command...
:ejabberd_c2s.open_session(%{user: "test2", server: "localhost", resource: "tkae1", sid: 6, ip: "localhost", auth_module: "shaper"})
But it giving error that no function_clause matching function ejabberd_c2s.changeshaper/1 .
What is the correct format of argument that I need to send to ejabberd_c2s.open_session function.
The open_session function's definition in ejabberd_c2s module is as follows:
open_session(#{user := U, server := S, resource := R,sid := SID, ip := IP, auth_module := AuthModule} = State)

The State you provide to open_session is later passed to change_shaper. And change_shaper expects some other fields in the State, look at its definition: shaper and lserver.

Related

How do I expose a UDP service externally on Google Kubernetes Engine (GKE) using the ingress-nginx controller?

I'm looking for some guidance on exposing UDP services on GKE using the ingress-nginx controller. After following the instructions on https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/ I was able to access it when deploying to a local minikube VM using the ConfigMap method. However, when I deploy to GKE the services are unreachable over the IP of the ingress controller service.
I see the ports (1053 and 15353) on the controller are mapped correctly:
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx ingress-nginx-controller LoadBalancer 10.51.252.115 <redacted> 80:32307/TCP,443:30514/TCP,1053:32764/UDP,15353:31385/UDP 54d
The cluster itself was created using the google_container_cluster Terraform module with default settings and the controller works well handling HTTPS traffic. One thing I did notice is that the auto-generated firewall rules omit UDP for the specified ports, and use TCP instead. Manually adding a UDP firewall rule for those ports didn't work.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
k8s-fw-a62a982b26a034e0e97258af6717b8b0 cluster-network-labs-us-west1 INGRESS 1000 tcp:80,tcp:443,tcp:1053,tcp:15353 False
I've deployed a simple UDP ping-pong server which works both locally on bare metal and on minikube as a kubernetes service using the ingress-nginx controller. That same controller with an identical configuration causes client requests to time out.
Server
package server
import (
"fmt"
"net"
"os"
"time"
"github.com/spf13/cobra"
)
func response(udpServer net.PacketConn, addr net.Addr, buf []byte) {
fmt.Println("msg", string(buf))
time := time.Now().Format(time.ANSIC)
responseStr := fmt.Sprintf("%v. msg: %v", time, string(buf))
udpServer.WriteTo([]byte(responseStr), addr)
}
var Command = &cobra.Command{
Use: "server",
Short: "Debug UDP server.",
Long: `Provides a UDP server endpoint which responds to pings.`,
RunE: func(cmd *cobra.Command, args []string) error {
udpServer, err := net.ListenPacket("udp", fmt.Sprintf(":%d", serverPort))
if err != nil {
return err
}
defer udpServer.Close()
fmt.Fprintf(os.Stdout, "listening :%d\n", serverPort)
for {
buf := make([]byte, 1024)
_, addr, err := udpServer.ReadFrom(buf)
if err != nil {
continue
}
go response(udpServer, addr, buf)
}
},
}
var serverPort int
func init() {
Command.PersistentFlags().IntVar(&serverPort, "port", 1053, "Port to open an listen for UDP packets")
}
Client
package client
import (
"fmt"
"net"
"os"
"github.com/spf13/cobra"
)
var Command = &cobra.Command{
Use: "client",
Short: "Debug UDP client.",
Long: `Provides a UDP client endpoint which responds to pings.`,
RunE: func(cmd *cobra.Command, args []string) error {
udpServer, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", queryHost, queryPort))
if err != nil {
return err
}
conn, err := net.DialUDP("udp", nil, udpServer)
if err != nil {
return err
}
defer conn.Close()
_, err = conn.Write([]byte(msg))
if err != nil {
return err
}
received := make([]byte, 1024)
_, err = conn.Read(received)
if err != nil {
println("Read data failed:", err.Error())
os.Exit(1)
}
println(string(received))
return nil
},
}
var msg string
var queryHost string
var queryPort int
func init() {
Command.PersistentFlags().StringVar(&msg, "msg", "echo", "Message used to send ping/pong requests over UDP")
Command.PersistentFlags().StringVar(&queryHost, "host", "127.0.0.1", "Host used to send ping/pong requests over UDP")
Command.PersistentFlags().IntVar(&queryPort, "port", 1053, "Port used to send ping/pong requests over UDP")
}
Has anyone seem something similar to this or have any ideas on where I can dig in further?
Thanks
Versions:
ingress-nginx helm chart - 4.4.0
ingress-nginx - 1.5.1
Kubernetes - v1.24.5-gke.600
registry.terraform.io/hashicorp/google - v4.43.0
As per this SO1 & Official Doc it is not possible to expose a UDP service externally on GKE.
But as per the referral document you mentioned it is possible to using NGINX Ingress.
Ingress does not support TCP or UDP services. For this reason this Ingress controller uses the flags --tcp-services-configmap and --udp-services-configmap to point to an existing config map where the key is the external port to use and the value indicates the service to expose using the format: <namespace/service name>:<service port>:[PROXY]:[PROXY].
This guide is describing how it can be achieved using minikube but doing this on a on-premises kubernetes is different and requires a few more steps.
Please go through SO for more information.
Make sure if you are exposing your service which LoadBalnacer type it's creating. With Nginx ingress by default, it might be creating the TCP load balancer only which might be supporting the TCP not sure if Nginx ingress supports the UDP or not.
Network Load Balancer is a good option if you want to expose the UDP service directly as type:LoadBalancer, as it supports the UDP/TCP both.
Ref : https://stackoverflow.com/a/69709859/5525824
Ref for LB service
apiVersion: v1
kind: Service
metadata:
name: udp-service
spec:
selector:
log: "true"
ports:
- name: udp-input
port: 3333
protocol: UDP
targetPort: 3333
type: LoadBalancer
For Nginx you would like to give this try : https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/ OR https://github.com/kubernetes/ingress-nginx/issues/4370
apiVersion: v1
kind: ConfigMap
metadata:
name: udp-services
namespace: ingress-nginx
data:
53: "kube-system/kube-dns:53"

Ejabberd - ejabberd_auth_external:failure:103 External authentication program failed when calling 'check_password'

I already have a schema of users with authentication-key and wanted to do authentication via that. I tried implementing authentication via sql but due to different structure of my schema I was getting error and so I implemented external-authentication method. The technologies and OS used in my application are :
Node.JS
Ejabberd as XMPP server
MySQL Database
React-Native (Front-End)
OS - Ubuntu 18.04
I implemented the external authentication configuration as mentioned in https://docs.ejabberd.im/admin/configuration/#external-script and took php script https://www.ejabberd.im/files/efiles/check_mysql.php.txt as an example. But I am getting the below mentioned error in error.log. In ejabberd.yml I have done following configuration.
...
host_config:
"example.org.co":
auth_method: [external]
extauth_program: "/usr/local/etc/ejabberd/JabberAuth.class.php"
auth_use_cache: false
...
Also, is there any external auth javascript script?
Here is the error.log and ejabberd.log as mentioned below
error.log
2019-03-19 07:19:16.814 [error]
<0.524.0>#ejabberd_auth_external:failure:103 External authentication
program failed when calling 'check_password' for admin#example.org.co:
disconnected
ejabberd.log
2019-03-19 07:19:16.811 [debug] <0.524.0>#ejabberd_http:init:151 S:
[{[<<"api">>],mod_http_api},{[<<"admin">>],ejabberd_web_admin}]
2019-03-19 07:19:16.811 [debug]
<0.524.0>#ejabberd_http:process_header:307 (#Port<0.13811>) http
query: 'POST' <<"/api/register">>
2019-03-19 07:19:16.811 [debug]
<0.524.0>#ejabberd_http:process:394 [<<"api">>,<<"register">>] matches
[<<"api">>]
2019-03-19 07:19:16.811 [info]
<0.364.0>#ejabberd_listener:accept:238 (<0.524.0>) Accepted connection
::ffff:ip -> ::ffff:ip
2019-03-19 07:19:16.814 [info]
<0.524.0>#mod_http_api:log:548 API call register
[{<<"user">>,<<"test">>},{<<"host">>,<<"example.org.co">>},{<<"password">>,<<"test">>}]
from ::ffff:ip
2019-03-19 07:19:16.814 [error]
<0.524.0>#ejabberd_auth_external:failure:103 External authentication
program failed when calling 'check_password' for admin#example.org.co:
disconnected
2019-03-19 07:19:16.814 [debug]
<0.524.0>#mod_http_api:extract_auth:171 Invalid auth data:
{error,invalid_auth}
Any help regarding this topic will be appreciated.
1) Your config about the auth_method looks good.
2) Here is a python script I've used and upgraded to make an external authentication for ejabberd.
#!/usr/bin/python
import sys
from struct import *
import os
def openAuth(args):
(user, server, password) = args
# Implement your interactions with your service / database
# Return True or False
return True
def openIsuser(args):
(user, server) = args
# Implement your interactions with your service / database
# Return True or False
return True
def loop():
switcher = {
"auth": openAuth,
"isuser": openIsuser,
"setpass": lambda(none): True,
"tryregister": lambda(none): False,
"removeuser": lambda(none): False,
"removeuser3": lambda(none): False,
}
data = from_ejabberd()
to_ejabberd(switcher.get(data[0], lambda(none): False)(data[1:]))
loop()
def from_ejabberd():
input_length = sys.stdin.read(2)
(size,) = unpack('>h', input_length)
return sys.stdin.read(size).split(':')
def to_ejabberd(result):
if result:
sys.stdout.write('\x00\x02\x00\x01')
else:
sys.stdout.write('\x00\x02\x00\x00')
sys.stdout.flush()
if __name__ == "__main__":
try:
loop()
except error:
pass
I didn't created the communication with Ejabberd from_ejabberd() and to_ejabberd(), and unfortunately can't find back the sources.

Cannot connect to AWS RDS PostgreSQL with Golang using Helm Charts

I am unable to connect to AWS RDS PostgeSQL when running Helm Chart for a Go App (GORM). All credentials are stored in a kubernetes secret, and the secret is being used in the helm chart.
Few Points:
Able to connect locally just fine.
The PostgreSQL database is already created in RDS, and made sure that the kubernetes secret as matches with the same creds.
Docker image is pushed and pulled from Gitlab without any errors.
Command "helm ls" displays the deployment status as "DEPLOYED"
When taking "kubectl get pod", I get STATUS as "CrashLoopBackoff"
When taking "kubectl describe pod", I get back MESSAGE "Back-off restarting failed container"
I then take "kubectl logs pod_name" to track the error, and get back the following:
failed to connect to the database
dial tcp 127.0.0.1:5432: connect: connection refused
(Not sure why it is still specifying "127.0.0.1" when i have the secret mounted)
Unable to exec into the pod because it is not running.
I have tried:
Secure a connection in the same cluster from a different pod using psql to ensure that the creds in the secret are in sync with what was set up in RDS PostgreSQL
Changing the api from DB_HOST, to host=%s
Tried connecting using fmt.Sprintf, as well as os.Getenv
"Versions"
GO version:
go1.11.1 darwin/amd64
DOCKER version:
Client:
Version: 18.06.1-ce
API version: 1.38
API.GO (file)
package controllers
import (
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
_ "gitlab.torq.trans.apps.ge.com/503081542/torq-auth-api/models"
)
var err error
type API struct {
Database *gorm.DB
Router *mux.Router
}
func (api *API) Initialize(opts string) {
// Initialize DB
dbinfo := os.Getenv("DB_HOST, DB_USER, DB_PASSWORD, DB_NAME,
DB_PORT sslmode=disable")
// dbinfo := os.Getenv("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable")
api.Database, err = gorm.Open("postgres", dbinfo)
if err != nil {
log.Print("failed to connect to the database")
log.Fatal(err)
}
// Bind to a port and pass our router in
// log.Fatal(http.ListenAndServe(":8000", handlers.CORS() .
(api.Router)))
fmt.Println("Connection established")
log.Printf("Postgres started at %s PORT", config.DB_PORT)
// MODELS
type application struct {
ID string `json:"id" gorm:"primary_key"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
Name string `json:"name"`
Ci string `json:"ci"`
}
type Cloud struct {
ID string `json:"id" gorm:"primary_key"`
Name string `json:"name"`
}
fmt.Println("Tables are created")
// Enable this line for DB logging
api.Database.LogMode(true)}
// Initialize Router
api.Router = mux.NewRouter()
api.Router.HandleFunc("/api/v1/applications",
api.HandleApplications)
api.Router.HandleFunc("/api/v1/application/{id}",
api.HandleApplication)
api.Router.HandleFunc("/api/v1/clusters", api.handleClusters)
}
I am not exactly sure where the issue could be here, this is a learning experience for myself. Any ideas would be appreciated.
Thanks in advance!
I think your database initialization code is not doing what you want. Try something like this
var driver = "postgres"
var name = os.Getenv("DB_NAME")
var host = os.Getenv("DB_HOST")
var user = os.Getenv("DB_USER")
var pass = os.Getenv("DB_PASSWORD")
var conn = fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", host, user, pass, name)
api.Database, err := gorm.Open(driver, conn)

Connecting to postgresql from lapis

I decided to play with lapis - https://github.com/leafo/lapis, but the application drops when I try to query the database (PostgreSQL) with the output:
2017/07/01 16:04:26 [error] 31284#0: *8 lua entry thread aborted: runtime error: attempt to yield across C-call boundary
stack traceback:
coroutine 0:
[C]: in function 'require'
/usr/local/share/lua/5.1/lapis/init.lua:15: in function 'serve'
content_by_lua(nginx.conf.compiled:22):2: in function , client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:8080"
The code that causes the error:
local db = require("lapis.db")
local res = db.query("SELECT * FROM users");
config.lua:
config({ "development", "production" }, {
postgres = {
host = "0.0.0.0",
port = "5432",
user = "wars_base",
password = "12345",
database = "wars_base"
}
})
The database is running, the table is created, in table 1 there is a record.
What could be the problem?
Decision: https://github.com/leafo/lapis/issues/556
You need to specify the right server IP in the host parameter.
The IP you have specified 0.0.0.0 is not a valid one, and normally it is used when you specify a listen address, with the meaning of "every address".
Usually you can use the '127.0.0.1' address during development.

CreateSession: no reachable servers - mgo

I'm trying to connect to MongoDB Atlas free cluster using mgo.
Golang Code -
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"time"
"log"
)
const (
AuthDatabase = "mydatabase"
AuthUserName = "databaseadmin"
AuthPassword = "databasepassword"
ReplicaSetName = "myproject-shard-0"
)
func main(){
MongoDBHosts := []string{
"myproject-shard-00-00-w4vds.mongodb.net:27017",
"myproject-shard-00-01-w4vds.mongodb.net:27017",
"myproject-shard-00-02-w4vds.mongodb.net:27017",
}
mongoDBDialInfo := &mgo.DialInfo{
Addrs: MongoDBHosts,
Timeout: 60 * time.Second,
Database: AuthDatabase,
Username: AuthUserName,
Password: AuthPassword,
ReplicaSetName: ReplicaSetName,
}
mongoSession, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
log.Fatalf("CreateSession: %s\n", err)
}
defer mongoSession.Close()
fmt.Printf("Connected to replica set %v!\n", mongoSession.LiveServers())
}
Error Message -
CreateSession: no reachable servers
Environment
I'm using mongodb free cluster with Google App Engine GO SDK
To connect to MongoDB Atlas, you need SSL
Prerequisites
TLS/SSL
Clients must have support for TLS/SSL to connect to an Atlas cluster.
Clients must have support for the SNI TLS extension to connect to an Atlas M0 Free Tier cluster.
Whitelist
To access a cluster, you must connect from an IP address on the Atlas group’s IP whitelist. If you need to add an IP address to the whitelist, you can do so in the Connect dialog. You can also add the IP address from the Security tab.
Thus I had to change the following piece of code
mongoDBDialInfo := &mgo.DialInfo{
Addrs: MongoDBHosts,
Timeout: 60 * time.Second,
Database: AuthDatabase,
Username: AuthUserName,
Password: AuthPassword,
ReplicaSetName: ReplicaSetName,
}
mongoDBDialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
return conn, err
}
I had to import the following too
"crypto/tls"
"net"