Write a Golang program that serves as a RESTful API proxy for Elasticsearch, providing additional security features such as authentication and rate limiting. The program should accept command line arguments for the Elasticsearch host, port, and API key, as well as configuration options for the rate limiting rules.

```go
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"golang.org/x/time/rate"
)

type RateLimiter struct {
	rate  int
	burst int
}

var elasticsearchHost string
var elasticsearchPort int
var apiKey string
var rateLimiters map[string]*rate.Limiter

func init() {
	flag.StringVar(&elasticsearchHost, "host", "localhost", "Elasticsearch host")
	flag.IntVar(&elasticsearchPort, "port", 9200, "Elasticsearch port")
	flag.StringVar(&apiKey, "apikey", "", "API key for authentication")

	rateLimiters = make(map[string]*rate.Limiter)
}

func getRateLimiter(ip string) *rate.Limiter {
	if limiter, exists := rateLimiters[ip]; exists {
		return limiter
	}
	newLimiter := rate.NewLimiter(rate.Every(time.Minute), 100)
	rateLimiters[ip] = newLimiter
	return newLimiter
}

func proxyHandler(w http.ResponseWriter, r *http.Request) {
	ip := strings.Split(r.RemoteAddr, ":")[0]
	limiter := getRateLimiter(ip)

	if !limiter.Allow() {
		http.Error(w, "Too many requests", http.StatusTooManyRequests)
		return
	}

	url := fmt.Sprintf("http://%s:%d%s", elasticsearchHost, elasticsearchPort, r.URL.Path)
	req, err := http.NewRequest(r.Method, url, r.Body)
	if err != nil {
		http.Error(w, "Error creating request", http.StatusInternalServerError)
		return
	}

	for name, values := range r.Header {
		for _, value := range values {
			req.Header.Add(name, value)
		}
	}

	req.Header.Set("Authorization", fmt.Sprintf("ApiKey %s", apiKey))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		http.Error(w, "Error forwarding request", http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		http.Error(w, "Error reading response body", http.StatusInternalServerError)
		return
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		http.Error(w, "Error unmarshalling JSON", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(jsonResponse)
}

func main() {
	flag.Parse()
	router := mux.NewRouter()
	router.PathPrefix("/").HandlerFunc(proxyHandler)

	fmt.Printf("Starting proxy server on :8080\n")
	http.ListenAndServe(":8080", router)
}
```

This Golang program serves as a RESTful API proxy for Elasticsearch with additional security features such as authentication and rate limiting. It accepts command line arguments for the Elasticsearch host, port, and API key.

To run this program, you need to have Go installed on your system. Save the code in a file named `main.go` and then execute the following commands:

```sh
go mod init elasticsearch-proxy
go get -u github.com/gorilla/mux
go build
./elasticsearch-proxy --host=<ElasticsearchHost> --port=<ElasticsearchPort> --apikey=<APIKey>
```

Replace `<ElasticsearchHost>`, `<ElasticsearchPort>`, and `<APIKey>` with appropriate values.

The program listens on port 8080 and forwards incoming requests to the specified Elasticsearch instance after checking the rate limits. The rate limiter is configured to allow 100 requests per minute for each IP address. You can modify the rate limiting rules by changing the values in the `getRateLimiter` function.

Please note that this is a basic implementation and may not cover all possible scenarios or edge cases. For production use, consider using more advanced libraries and techniques to handle authentication, rate limiting, and other security features.